Codeforces Round #378 (Div. 2)A.B.C

来源:互联网 发布:大势至usb软件 编辑:程序博客网 时间:2024/06/06 07:27

又是一次智障的跌在C题,大哭不多记了,看代码。。。

A题:

题意:

虫子每次都可以跳到他所在位置前面的第一个A,E,I,O,U,Y的出现位置,并且最后可以跳到最后。

思路:

暴力扫一遍位置就行了,注意下尾部字符串末尾终止处理,比赛时候智障了。

#include <iostream>#include <stdio.h>#include <cstring>using namespace std;char s[100005];int a[10005];int main(){    scanf("%s",&s);    int ans=0;    int tep=0;    int len=0;    a[1]=0;    for(int i=0;i<strlen(s);i++)    {        if(s[i]=='A'||s[i]=='E'||s[i]=='O'||s[i]=='I'||s[i]=='U'||s[i]=='Y')        {            a[++len]=i+1;        }    }    a[++len]=1+strlen(s);    for(int i=1;i<=len;i++)    {        //cout<<a[i]<<" ";        ans=max(a[i]-a[i-1],ans);    }    cout<<ans<<endl;    return 0;}


B题:

题意:士兵走步,第一个数据N,下面有N对, 

第一个数据表示第一次迈左腿的人数, 第二个数据表示第一次迈右腿的人数。

询问,你只能交换一次,也可以不交换,使得所有的第一次迈左腿的,与右腿的人数差值的绝对值最大

思路:

先记录左腿,右腿依次的和,然后暴力交换每一行。

#include <iostream>#include <stdio.h>#include <cstring>using namespace std;char s[100005];int a[10005];int l[1000005];int r[1000005];int lx[1000005];int rx[1000005];int main(){    int k;    cin>>k;    int suml=0,sumr=0;    for(int i=1;i<=k;i++)    {        cin>>l[i]>>r[i];        suml+=l[i];        sumr+=r[i];    }    int maxx=sumr-suml;    if(maxx<0)        maxx=-maxx;    int ans=0;    for(int i=1;i<=k;i++)    {        int tel=suml-l[i]+r[i];        int ter=sumr-r[i]+l[i];        int maxt=tel-ter;        if(maxt<0)            maxt=-maxt;        if(maxt>maxx)        {            maxx=maxt;            ans=i;        }    }    cout<<ans<<endl;    return 0;}

C题:

这题编了一个半小时不出,最后24秒发现扫一下就可以了,第二天15分钟就AC了。真是个智障哭

题意:

第一行N,表示第二行有n个数字

第二行有N个数字

第三行K,表示第四行有K个数字

第四行 K个数字。

题目背景是:  第二行都是怪物,数字大的吃数字小的,并且只能吃掉相邻的,吃掉后变为两个数字的和,询问能否通过怪物互相吃掉对方,变成第四行的数字。

  思路:

注意点四行的K个数字,如果我们拿到第一个数字的话,那一定这个数字是通过第二行前X个构造的,第二个数字,必定是通过第二行前X+1->Y个数字构造的,那么我们只需要如此做就AC嘞!(注意,因为怪物不能直接互换位置,所以只需要扫一下和就行了)

1: 扫一下第二行,记录数字的和,如果数字的和==第四行的第i个数字,就把当前记录清空,继续找i+1个,否则找不到就跳出去。(具体见程序solve函数有注释)

2: 如果可以将这些数字经过若干步,变成第四行要求的数字,那么我们只需要再重新调用下之前的函数,把操作打印出来即可。

3: (掉坑里的一步): 什么也别想,直接暴力扫一下,数据很小,我们只需要记录下当前的最大值的位置,然后进行左或者右的判断,以及开始位置。

如果没看懂,看代码:

#include <iostream>#include <stdio.h>#include <cstring>using namespace std;int a[10005];int need[10005];int pos[10005];int vis[10005];int all;int solve(int x,int op ){    memset(vis,0,sizeof(vis));    int maxx=0;    int cnt=0;    //记录最大值所在的位置。如果都是最大值那就不成立,第一次调用solve函数时候的判断    for(int i=pos[x-1]+1;i<=pos[x];i++)    {        if(a[i]>maxx)        {            cnt=0;            vis[++cnt]=i;            maxx=a[i];        }        else if(a[i]==maxx)        {            vis[++cnt]=i;        }    }    int t=0;    for(int i=pos[x-1]+1;i<=pos[x];i++)    {        if(a[i]==maxx)            t++;    }    if(t!=1&&t==pos[x]-pos[x-1])        return 0;     //第二次调用solve 函数时候的输出:       if(op==1)    {        int bt;        int l=1,r=1;        //判断哪个最大位置可以走,如果最大位置吃掉了任意一个数字,比如 3 3 1   第二个三吃掉1 就变成了最大的最大,因为即便之前有和他相同的,但是他+1必定比之前的大        for(int i=1;i<=cnt;i++)        {//扫面左边和右边            l=1,r=1;            if(vis[i]==pos[x-1]+1||(vis[i]!=pos[x-1]+1&&vis[i]==vis[i-1]+1) )                l=0;            if(vis[i]==pos[x]||vis[i]==vis[i+1]-1  )                r=0;            if(l==1||r==1)               {                bt=vis[i];                break;               }        }//下面的步骤不要忘记脚标的改变,        if(l==1)        {            //如果可以往左吃,先吃到最左再吃到最右,注意输出的位置            for(int i=bt;i>pos[x-1]+1;i--)            {                printf("%d ",i-all);//当前位置                 printf("L\n");            }            for(int i=bt;i<pos[x];i++)            {                printf("%d ",pos[x-1]+1-all);//一直是最左                printf("R\n");            }        }        else if(r==1)//和最左相同,各位自己寻思下。        {            for(int i=bt;i<pos[x];i++)            {                printf("%d ",bt-all);                printf("R\n");            }            for(int i=bt;i>pos[x-1]+1;i--)            {                printf("%d ",i-all);                printf("L\n");            }        }    }    return 1;}int main(){    int n;    cin>>n;    for(int i=1;i<=n;i++)        scanf("%d",&a[i]);    int k;    cin>>k;    for(int i=1;i<=k;i++)        {            scanf("%d",&need[i]);        }    int sum=0;    int cnt=1;    int over=0;    int i;    //下面的一步,如果不能组合成要求的数字就结束。    for( i=1;i<=n;i++)    {        sum+=a[i];        if(sum==need[cnt])        {            pos[cnt]=i;            sum=0;            cnt++;        }        else if(sum>need[cnt])        {            over=1;            break;        }    }    pos[0]=0;    if(i!=n+1||cnt!=k+1)        over=1;    if(over)        printf("NO\n");    if(over==0)    {        //下面的一步,如果可以组合成,但是不满足可以互相吃掉的要求 就比如 2 2 2 可以构成6 但是实际上不可以互相吃掉就跳出        //详情见solve函数        for( i=1;i<=k;i++)        {            if(solve(i,0)==0)            {                over=1;                break;            }        }        if(over)        {            printf("NO\n");        }        else        {            printf("YES\n");            all=0;            //都已经判断OK了。输出            //注意all数字是改脚标值的。            for( i=1;i<=k;i++)            {                solve(i,1);                all+=pos[i]-pos[i-1]-1;            }        }    }    return 0;}

0 0
原创粉丝点击