2019 浙江省賽(The 16th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple)

目錄

B Element Swapping(數學問題)

E Sequence in the Pocket(思維)

F Abbreviation(簽到題)

G Lucky 7 in the Pocket(簽到題)

H Singing Everywhere(分類討論+思維)

I Fibonacci in the Pocket(規律+高精度求餘)


B Element Swapping(數學問題)

【題意】一個序列,交換第 i 個元素和第 j 個元素,有 x 和 y 的計算公式;給出交換後的序列以及原序列的x和y的值;求可能有多少種交換方法

【分析】數學公式問題

設交換後的序列對應的x、y分別是M,N

那麼有

(i-j)(a_{i}-a_{j})=x-M

(i-j)(a_{i}^2-a_{j}^2)=y-N      

a_{i}+a_{j}=\frac{y-N}{x-M}

所以,只要求出a[i]就可以知道a[j]的值,注意求出的a[i]與a[j]還要滿足M,x的關係

如果a[i]=a[j],兩兩組合,一共有n*(n+1)/2種組合;這種情況特判一下;

其他的情況分類討論一下即可;注意數組和num是long long的,int的話是會爆的然後就會wa的...

【代碼】

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn=2e5+10;
ll a[maxn];
map<int,int>mp;

int main()
{
    int t; scanf("%d", &t);
    while(t--)
    {
        ll n, x, y;
        scanf("%lld%lld%lld", &n, &x, &y);
        ll M = 0, N = 0, ans = 0;
        mp.clear();
        for(int i = 1; i <= n; ++i)
        {
            scanf("%lld", &a[i]);
            M += i*a[i];
            N += i*a[i]*a[i];
            mp[a[i]]++;
        }
        if(x == M && y == N)
        {
            map<int,int>::iterator it;
            for(it = mp.begin(); it != mp.end(); ++it)
            {
                ll num = it->second;
                ans += num*(num-1)/2;
            }
            printf("%lld\n", ans);
            continue;
        }
        if(x == M || y == N || (y-N)%(x-M) != 0)
        {
            printf("0\n");
            continue;
        }
        ll sum = (y-N)/(x-M);
        for(int i = 1; i <= n; ++i)
        {
            ll aj = sum - a[i];
            if(a[i] == aj || aj < 1 || ((x-M) % (a[i]-aj) != 0))continue;
            int cha = (M - x)/(a[i] - aj);
            int j = i-cha;
            if(j <= 0 || j > n || j <= i || a[j] != aj)continue;
            ans++;
        }
        printf("%lld\n", ans);
    }
    return 0;
}

E Sequence in the Pocket(思維)

【題意】給你一串序列,每次只能把某個元素移到最前面,問至少要移動多少次使得序列非降

【分析】

一段序列,如果要變成非降序列,那麼就要不斷維護序列;因爲要移動,所以每次都儘量把最大值放在序列後面即儘量不移動最大值;

即先排個序,排序之後每個數的位置其實就固定了,再跟原序列進行比較,如果同一個位置的值不相等,即該數是需要移動的,記錄需要移動的位置,輸出即可;

【代碼】

#include<bits/stdc++.h>
using namespace std;

const int maxn=1e5+10;
typedef long long ll;
ll a[maxn],b[maxn];

int main()
{
    int t;scanf("%d",&t);
    while(t--)
    {
        int n;scanf("%d",&n);
        for(int i=0;i<n;++i)
        {
            scanf("%lld",&a[i]);
            b[i]=a[i];
        }
        sort(a,a+n);
        int j=n-1;
        int ans=0;
        for(int i=n-1;i>=0;--i)
        {
            if(a[j]==b[i]) --j;
            else ans++;
        }
        printf("%d\n",ans);
    }
    return 0;
}

F Abbreviation(簽到題)

【題意】去掉讀入串中不在首位的'a', 'e', 'i', 'y', 'o', 'u'

【代碼】

#include<bits/stdc++.h>
using namespace std;

int main()
{
    int t;scanf("%d",&t);
    while(t--)
    {
        string s;cin>>s;
        int len=s.length();
        for(int i=0;i<len;++i)
        {
            if(i==0)printf("%c",s[i]);
            else
            {
                if(s[i]=='a' || s[i]=='e' || s[i]=='i' || s[i]=='o' || s[i]=='u' || s[i]=='y')continue;
                else printf("%c",s[i]);
            }
        }
        puts("");
    }
    return 0;
}

G Lucky 7 in the Pocket(簽到題)

【題意】輸出比讀入的數字大的最小的數(被7整除但不被4整除)

【代碼】

#include<bits/stdc++.h>
using namespace std;

int main()
{
    int t;scanf("%d",&t);
    while(t--)
    {
        int n;scanf("%d",&n);
        while(1)
        {
            if(n%7==0 && n%4!=0)
            {
                printf("%d\n",n);
                break;
            }
            n++;
        }
    }
    return 0;
}

H Singing Everywhere(分類討論+思維)

【題意】給出音調的序列,先升後降稱爲crack,每次最多可以刪掉一個音符,問最少要演奏多少個crack

【分析】分類討論一下即可;

首先統計一下原序列中crack 的總數,然後遍歷模擬刪掉每個音符的結果

刪掉第i個音符時,討論i+1、i-1 是峯的情況,並且要統計原序列這裏的峯的數量,最後相減取最大值即可

注意統計原序列裏的峯的數量時,不可以直接if-else if-else if,因爲如果是a[i]處於谷的時候,會同時滿足a[i-1]和a[i+1]是峯

【代碼】

#include<bits/stdc++.h>
using namespace std;

const int maxn=1e5+10;
int a[maxn];

int main()
{
    int t;scanf("%d",&t);
    while(t--)
    {
        int  n;scanf("%d",&n);
        for(int i=1;i<=n;++i)
            scanf("%d",&a[i]);
        a[0]=a[n+1]=99999999999;
        int cnt=0;
        for(int i=2;i<=n-1;++i)
            if(a[i]>a[i-1] && a[i]>a[i+1])
                cnt++;
        int ans=0;
        for(int i=2;i<=n-1;++i)
        {
            int n1=0,n2=0;
            if(a[i]>a[i-1] && a[i]>a[i+1])n1++;
            if(a[i-1]>a[i-2] && a[i-1]>a[i])n1++;
            if(a[i+1]>a[i] && a[i+1]>a[i+2])n1++;

            if(a[i-1]>a[i-2] && a[i-1]>a[i+1])n2++;
            else if(a[i+1]>a[i-1] && a[i+1]>a[i+2])n2++;

            //cout<<n1<<","<<n2<<endl;
            ans=max(ans,n1-n2);
        }
        //cout<<"cnt="<<cnt<<",ans="<<ans<<endl;
        ans=cnt-ans;
        printf("%d\n",ans);
    }
    return 0;
}

I Fibonacci in the Pocket(規律+高精度求餘)

【題意】求第a項到第b項斐波那契數列的和是奇數還是偶數

【分析】把斐波那契數列的前幾項寫出來就會發現,呈 奇數 奇數 偶數 排列;

因爲奇數+奇數=偶數,奇數+偶數=奇數,偶數+偶數=偶數

所以根據這個規律,可以把a和b的餘數求出來,看對應的是每一塊(3個數)的哪個數,然後分類討論即可

取餘的話,和大數除法相同,就是最後輸出餘數即可(上次被要求手動寫寫大數的幾個運算,果然印象深刻了許多!)

【代碼】

#include<bits/stdc++.h>
using namespace std;

int getMod(string s,int x)
{
   // string ans;
    int len=s.length();
    int d=0;
    for(int i=0;i<len;++i)
    {
        int num=s[i]-'0';
        int tmp=(d*10+num)/x;
     //   ans+=tmp+'0';
        d=d*10+num-tmp*x;
    }
   // cout<<"d="<<d<<endl;
    return d;
}
int main()
{
    int t;scanf("%d",&t);
    while(t--)
    {
        string a,b;
        cin>>a>>b;
        int n1=getMod(a,3);
        int n2=getMod(b,3);
        if(n1==1 && n2==1)printf("1\n");
        else if(n1==2 && (n2==2|| n2==0))printf("1\n");
        else if(n1==0 && n2==1)printf("1\n");
        else printf("0\n");
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章