码迷,mamicode.com
首页 > 其他好文 > 详细

浙江省程序设计竞赛2019

时间:2020-09-23 22:59:17      阅读:88      评论:0      收藏:0      [点我收藏+]

标签:ons   tle   tin   return   lap   ack   push   高精度   main   

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;
    }
}

 

浙江省程序设计竞赛2019

标签:ons   tle   tin   return   lap   ack   push   高精度   main   

原文地址:https://www.cnblogs.com/hulian425/p/13696004.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!