寒假练习赛20170109 (部分题解)

来源:互联网 发布:java date 上午下午 编辑:程序博客网 时间:2024/06/16 12:15

A:判断一个数是否是2,3,5的倍数。
题解:末尾是偶数的是2的倍数,末尾是0,5的是5的倍数。各个位和是3的倍数的是3的倍数.
代码:

#include <stdio.h>#include <stdlib.h>#include <algorithm>#include <iostream>#include <queue>#include <stack>#include <set>#include <map>#define bababaa printf("!!!!!!!\n")#define ll long longusing namespace std;string str;int main(){    while(cin>>str)    {        ll sum=0;        int len=str.length();        for(int i=0;i<len;i++)        {            sum+=str[i]-'0';        }        if(sum%3==0||(str[len-1]-'0')%2==0||(str[len-1]-'0')%5==0)            cout<<"YES"<<endl;        else            cout<<"NO"<<endl;    }}

B:一个数列ai,你可以选择任意长度的子区间(可以为0)将ai变成ai=ai*890+143)%10007,求n个数的最大和值。
题解:求出差值bi,求出bi的最大子段和。找到起点终点,加上原数列的和就好。
代码:

#include <stdio.h>#include <stdlib.h>#include <algorithm>#include <iostream>#include <queue>#include <stack>#include <set>#include <map>#define bababaa printf("!!!!!!!\n")#define ll long longusing namespace std;ll a[100006],b[100006],dp[100006];int main(){    int n;    while(cin>>n)    {        ll sum=0;        for(int i=1;i<=n;i++)        {            cin>>a[i];            sum+=a[i];            b[i]=(1890*a[i]+143)%10007-a[i];        }        dp[1]=b[1];        for(int i=2;i<=n;i++)        {            if(dp[i-1]>0)                dp[i]=dp[i-1]+b[i];            else             dp[i]=b[i];        }        int mx=-1;        int k=0;        for(int i=1;i<=n;i++)        {            if(dp[i]>mx)            {                mx=dp[i];                k=i;            }        }        int p=0;        for(int i=k;i>0;i--)        {            if(dp[i]<0)            {                p=i+1;                break;            }        }        for(int i=p;i<=k;i++)            sum+=b[i];        cout<<sum<<endl;    }}

C:高中生物,DNA链和RNA链的匹配。
代码:

#include <stdio.h>#include <stdlib.h>#include <algorithm>#include <iostream>#include <queue>#include <stack>#include <set>#include <map>#define bababaa printf("!!!!!!!\n")#define ll long longusing namespace std;char s1[10000],s2[10000];int main(){    int t,n;    cin>>t;    while(t--)    {        cin>>n;        cin>>s1;        cin>>s2;         bool flag=true;        for(int i=0;i<n;i++)        {            if(s1[i]=='A' && s2[i] == 'U') continue;            if(s1[i]=='T' && s2[i] == 'A') continue;            if(s1[i]=='C' && s2[i] == 'G') continue;            if(s1[i]=='G' && s2[i] == 'C') continue;            flag=false;        }        if(flag)            cout<<"YES"<<endl;        else            cout<<"NO"<<endl;    }}

D:博弈,证明不会。
代码;

#include <stdio.h>#include <stdlib.h>#include <algorithm>#include <iostream>#include <queue>#include <stack>#include <set>#include <map>#define bababaa printf("!!!!!!!\n")#define ll long longusing namespace std;char s1[10000],s2[10000];int main(){    int t,n;    cin>>t;    while(t--)    {        cin>>n;        if(n&1)            cout<<"1"<<endl;        else            cout<<"0"<<endl;    }}

E:给出你每插入一个数,逆序数的总数。问原序列?
解释样例:0 1 2
当第一个位置插入一个数时,逆序数的为0.
。。二。。。。。。。。。,。。。。。1.
。。三。。。。。。。。。,。。。。。2.
从后往前推,当第三个数插入后,个数由1变成2个, 说明前面有一个大于他的数,既他是序列中第二大的,就是2.
其他自己推。
建一棵线段树,优先判断右子树,每次查询后,更新即可。
代码:

#include <stdio.h>#include <stdlib.h>#include <algorithm>#include <iostream>#include <queue>#include <stack>#include <set>#include <map>#include <string.h>#define bababaa printf("!!!!!!!\n")#define ll long longusing namespace std;int n,t;const int N=50010;int a[N];int sum[N<<2];int output[N];void pushup(int rt){    sum[rt]=sum[rt<<1]+sum[rt<<1|1];}void build(int l,int r,int rt){    if(l==r)    {        sum[rt]=1;        return ;    }    int mid=(r+l)>>1;    build(l,mid,rt<<1);    build(mid+1,r,rt<<1|1);    pushup(rt);}int query(int l,int r,int k,int rt){    if(l==r)    {        sum[rt]=0;        return l;    }    int res;    int mid=(r+l)>>1;    if(sum[rt<<1|1]>=k)        res=query(mid+1,r,k,rt<<1|1);    else        res=query(l,mid,k-sum[rt<<1|1],rt<<1);    pushup(rt);    return res;}int main(){    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        for(int i=1; i<=n; i++)        {            scanf("%d",&a[i]);        }        build(1,n,1);        a[0]=0;        for(int i=n; i>=1; i--)        {            int cnt=a[i]-a[i-1];            output[i]=query(1,n,cnt+1,1);        }        for(int i=1; i<n; i++)        {            printf("%d ",output[i]);        }        printf("%d\n",output[n]);    }}

F:给你一个方程,求最大最小值,暴力即可。
代码:

#include <stdio.h>#include <stdlib.h>#include <algorithm>#include <iostream>#include <queue>#include <stack>#include <set>#include <map>#define bababaa printf("!!!!!!!\n")#define ll long longusing namespace std;char s1[10000],s2[10000];int a,b,c,d,e;int main(){    int t,n;    cin>>t;    while(t--)    {        int mx=-10000000000;        int mi=100000000000;        cin>>a>>b>>c>>d>>e;        for(int i=d;i<=e;i++)        {            mx=max(mx,a*i*i+b*i+c);            mi=min(mi,a*i*i+b*i+c);        }        cout<<mx<<" "<<mi<<endl;    }    }

G: 原文翻译如下:
从前,有n只萌萌的GT,他们分成了两组在一起玩游戏。他们会排列成一排,第i只GT会随机得到一个能力值bi。在第i秒的时候,第ii只GT可以消灭掉所有排在他前面的和他不是同一组的且能力值小于他的GT。
为了使游戏更加有趣,GT的首领GTW会发功m次,第i次发功的时间为ci,则在第ci​​秒结束后,b1,b2,…,bci都会增加1。
现在,GTW想知道在第n秒之后,会有几只GT存活下来。
总共T行,第i行表示第i组数据中,GT存活的个数。
题解:可以得知,最后一个GT不会死,想到倒推,从后面维护两个组的最大值
代码:

#include <stdio.h>#include <stdlib.h>#include <algorithm>#include <iostream>#include <queue>#include <stack>#include <set>#include <map>#include <string.h>#define bababaa printf("!!!!!!!\n")#define ll long longusing namespace std;struct node{    int pi,nl;}a[50050];int c[1000005];int t,n,m,x;int main(){    scanf("%d",&t);    while(t--)    {        memset(c,0,sizeof(c));        scanf("%d%d",&n,&m);        for(int i=1;i<=n;i++)        {            scanf("%d%d",&a[i].pi,&a[i].nl);            //cin>>a[i].pi>>a[i].nl;              }        for(int i=1;i<=m;i++)        {            //cin>>x;            scanf("%d",&x);            c[x]++;        }        int mx0=0;        int mx1=0;        int tot=0;        int sum=0;        for(int i=n;i>=1;i--)        {            tot+=c[i];            a[i].nl+=tot;            if(a[i].pi==1)            {                if(mx0>a[i].nl)                    sum++;                mx1=max(mx1,a[i].nl);            }            else            {                if(mx1>a[i].nl)                    sum++;                mx0=max(mx0,a[i].nl);            }             }        printf("%d\n",n-sum);    }}

H:不会

0 0
原创粉丝点击