ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

浙江省程序设计竞赛2019

2020-09-19 14:04:20  阅读:684  来源: 互联网

标签:cnt 竞赛 int ++ 2019 && 程序设计 include se


B - Element Swapping

 ZOJ - 4101 

题意:

题解

可以求得a[i] + a[j] = d2/d1

 

#include <iostream>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <assert.h>
#include <map>
#include <set>
#include <bitset>
#include <iomanip>
#include <stack>
#include <deque>
#include <unordered_map>
#include <cmath>
using namespace std;
#define STDIN                      \
    freopen("in.txt", "r", stdin); \
    freopen("out.txt", "w", stdout);

#define int long long
inline int read(){char tempt = getchar();int x = 0, f = 0;while (tempt < '0' || tempt > '9')f |= tempt == '-', tempt = getchar();while (tempt >= '0' && tempt <= '9')x = x * 10 + tempt - '0', tempt = getchar();return f ? -x : x;}
int n, x, y;
const int N = 1e5 + 10;
int a[N];
int num[N];
vector<int> get_divisors(int x)
{
    vector<int> res;
    for (int i = 1; i <= min(x / i, n); i ++ )
        if (x % i == 0)
        {
            res.push_back(i);
            if (i != x / i &&((x/i)<=n)) res.push_back(x / i);
        }
    sort(res.begin(), res.end());
    return res;
}
signed main()
{
    //STDIN
    int t;
    cin >> t;
    for (int _ = 1; _ <= t; _++)
    {
        
        n = read(), x = read(), y = read();
        memset(num, 0, sizeof num);
        for (int i = 0; i < n; i++)
        {
            // scanf("%lld", &a[i]);
            a[i] = read();
            num[a[i]]++;
        }
        int sum1 = 0;
        int sum2 = 0;
        for (int i = 0; i < n; i++)
        {
            sum1 += (i+1)*a[i];
        }
        for (int i = 0; i < n; i++)
        {
            sum2 += (i+1)*a[i]*a[i];
        }
        int d1 = sum1-x;
        int d2 = sum2-y;
        // cout << d1 << " " << d2 << endl;
        if (d1 == 0 && d2 == 0)
        {
            int cnt = 0;
            map<int,int> ma;
            for (int i = 0;  i< n; i++)
            {
                if (ma.count(a[i]) >= 1) cnt += ma[a[i]];
                ma[a[i]]++;
            }
            cout << cnt << endl;
            continue;
        }
        if (d1 == 0 || d2 == 0)
        {
            cout << 0 << endl;
            continue;
        }
        if (d2%d1!=0){
            cout << 0 << endl;
            continue;
        }
        int xx = d2/d1;
        // cout << xx << endl;
        if (xx <= 0) 
        {
            cout << 0 << endl;
            continue;
        }
        map<int, set<int> > ma;
        int ans = 0;
        vector<int> tmp = get_divisors(d1);
        for (int i = 0; i < n; i++)
        {
            // int d = xx-a[i];
            // if (a[i] == d) continue;
            // if (ma.count(d) >=1 && d1%(a[i] - d) == 0 &&(d2%(a[i]*a[i]-d*d) == 0))
            // {
            //     // d1%(i-j)
            //     auto &se = ma[d];
            //     for (auto &p:tmp)
            //     {
            //         // if (i-p > i-1)
            //         if (p >= i) break;
            //         if (se.find(i-p) != se.end() && (d2%p == 0)) ans++;
            //     }
                
            // }
            // ma[a[i]].insert(i);
            int aj = xx - a[i];
            int s = aj - a[i];
            if (s!= 0 && aj > 0 && d1%s == 0)
            {
                int cnt = (d1)/s;
                cnt += i;
                if (cnt <= n && cnt > i && a[cnt] ==aj) ans++;
            }
        }
        printf("%lld\n", ans);
    }
    // cout <<get_divisors(100000).size() <<endl;

}
View Code

 

 

 

 

ZOJ - 4104

题意:

一个数列,每次操作可以将任意一个数提至数列最前端,问至少操作几次可以将数列变为非降数列?

题解:

可以观察到,任何数列,都可以通过最多n-1次操作变成非降数列,我们在建一个与原来数组一样的数组,从后往前考虑,如果这个数的位置正确,则跳过,如果不正确,那么这个数肯定要往前提至少一次,那么对于这个数前面的数,他们都会往后移一个

我们定义一个变量记录移动次数,cnt,那么当我们处理下一个数时,他的位置已经往后移了cnt个,那么让他与a[i+cnt]比较,如果相等,则跳过,如果不相等,说明在这个数之前操作的数,需要在往前移,那么cnt++。这样处理完cnt就是最后的答案。

const int N = 1e5 + 10;
int num[N];
signed main()
{
    // STDIN
    int t;
    cin >> t;
    for (int _ = 1; _ <= t; _++)
    {
        int n;
        cin >> n;
        vector<int> a(n), b(n);
        for (int i = 0; i < n; i++)
        {
            scanf("%d",&a[i]);
            b[i] = a[i];
        }
        sort(a.begin(), a.end());
        int cnt = 0;
        for (int i = n-1; i>= 0; i--)
        {
            if (a[(i+cnt)] != b[i])
            {
                cnt++;
            }
        }
        cout <<cnt << endl;
    }
}

F - Abbreviation

 ZOJ - 4105 

题意:

将字符串的元音字母删掉,注意第一个字母不删,输出处理后的字母

题解:水题

 

G - Lucky 7 in the Pocket

 ZOJ - 4106

水题

H - Singing Everywhere

 ZOJ - 4107

题意:

一个数列,如果a[i]>a[i-1] && a[i]>a[i+1],这样算一次破音,问当最多可以删掉一个数时,让破音数最少,最少的破音数是多少?

题解

暴力判断删掉每一个数删掉后的破音数,注意边界的处理

 

#define int long long

set<int> se;
signed main()
{
    //STDIN
    int t; cin >> t;
    for (int _ = 1; _ <= t; _++)
    {
        int n;
        cin >> n;
        vector<int> a;
        for (int i = 1; i <= n; i++)
        {
            int x;
            scanf("%lld", &x);
            a.push_back(x);
        }
        for (int i = 1; i < n-1; i++)
        {
            if (a[i] > a[i-1] && a[i] > a[i+1]) se.insert(i);
        }
        int ans = se.size();
        int res = ans;
        for (int i = 0; i < n; i++)
        {
            if (i == 0)
            {
                if (se.find(1) != se.end())
                {
                    res = min(ans-1, res);
                }
            }
            else if (i == n-1)
            {
                if (se.find(n-2) != se.end())
                {
                    res = min(ans-1, res);
                }
            }

            else{
                int t = ans;
                if (se.find(i) != se.end()) t--;
                if ( i-2 >=0)
                {
                    if ( a[i-1] > a[i-2] && a[i-1] > a[i+1])
                    {
                        if (se.find(i-1) == se.end()) t++;  
                    }
                    else {
                        if (se.find(i-1) != se.end()) t--;
                    }
                    
                }
                if (i+2 <= n-1 )
                {
                    if(a[i+1] > a[i-1] && a[i+1] > a[i+2])
                    {
                        if (se.find(i+1) == se.end()) t++;
                    }
                    else{
                        if (se.find(i+1) != se.end()) t--;
                    }
                    
                }
                res = min(t, res);
            }
        }
        cout << res << endl;
        se.clear();
    }
}

 

I - Fibonacci in the Pocket

 ZOJ - 4108 

题意:

求斐波那契数列的区间和是奇数还是偶数

题解:

找规律

 

int mod1(string a, int b) //高精度a除以单精度b
{
    int d = 0ll;
    for (int i = 0; i < a.size(); i++)  d = (d * 10 + (a[i] - '0')) % b;  //求出余数
    return d;
}
signed main()
{
   // STDIN
    int t;
    cin >> t;
    for (int _ = 1; _ <= t; _++)
    {
        string a, b;
        cin >> a >> b;
        int a1 = mod1(a,3);
        int b1 = mod1(b,3);
        if ((a1 == 1 && b1 == 2) ||(a1 == 0 && b1 == 0)||(a1 == 1 &&b1 == 0)|| (a1 == 2 && b1 == 1) ||(a1 == 0 && b1 == 2))
        {
            cout<< 0 << endl;
        } 
        else cout << 1 << endl;
    }
}

 

标签:cnt,竞赛,int,++,2019,&&,程序设计,include,se
来源: https://www.cnblogs.com/hulian425/p/13696004.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有