Codeforces Round #386 (Div. 2) A+B+C+D!

本文分享了一场编程比赛的解题思路及代码实现,包括简单的比例计算、字符串加密解密模拟、直线运动模拟及茶饮顺序安排等问题。

                                                              A. Compote


   水题(数据范围小都是水题),按照比例找最小的就行了,3min水过。

int main()
{
    int a,b,c;
    while(~scanf("%d%d%d",&a,&b,&c))
    {
        int ans=0;
        for(int i=1;i<=a;i++)
        {
            if(b>=2*i&&c>=4*i)
            {
                ans=max(ans,i+2*i+4*i);
            }
        }
        printf("%d\n",ans);
    }

    return 0;
}


                                                          B. Decoding


      题意:一个字符串给其加密的方式是每次取其出最中间的那个字符如果长度为偶数取左边的组成新的串然后在原串中删掉此位子上的字符。现在给出你密文与长度求明文。

     思路:模拟即可,可以用两个string存左右两边的,也可以用数组把每个位置加密后的状态存起来,然后利用数据范围小两层循环找到相应的位置输出即可。

const int N=1e6+7;
int a[N],v[N];
char s[N];
int main()
{
    int n;
    while(~scanf("%d%s",&n,s+1))
    {
        int x=n;
        int i,j;
        memset(v,0,sizeof(v));
        int len=1;
        if(n%2) i=j=(n+1)/2,j++;
        else i=j=n/2,j++;
        if(n%2)
        {
            a[len++]=i--;
            n--;
        }
        while(n)
        {
            if(n%2==0)
                a[len++]=i--;
            else
                a[len++]=j++;
            n--;
        }
        for(int i=1; i<=x; i++)
            for(int j=1; j<len; j++)
                if(i==a[j])
                {
                    printf("%c",s[j]);
                    break;
                }
        printf("\n");
    }
    return 0;
}


                                                          C. Tram

     模拟题,不用想复杂了,开始想得太复杂直接跳过这题,回来才发现原来也不难。

     题意:一段路为直线起点为0终点为s。一辆车从0到s来回匀速直线运动,走1m需要v1时间,小明从一个点q1出发去q2,走1m需要v2时间。求小明到达q2点最少需要多少时间。

    思路:其实到达终点只有两种情况,一种直接走过去,一种的乘车到达。而如果是乘车到达的话是取决于车到达终点的状态的。明白了这个就很好写了,总共5种情况,有很多细节需要注意一下。

int main()
{
    int s,p1,p2,v1,v2,pos,d;
    while(~scanf("%d%d%d%d%d%d%d",&s,&p1,&p2,&v1,&v2,&pos,&d))
    {
        if(p1==p2)
        {
            printf("0\n");
            continue;
        }
        int ans=abs(p2-p1)*v2;//直接到;
        //坐车到,如果最终是坐车到的话其实取决于车到达的时间;
        if(p2>p1)
        {
            if(d==1)//同向;
            {
                if(pos>p1)//车在前面
                {
                    int ans1=2*s*v1;
                    if(pos>p2) ans1-=abs(pos-p2)*v1;
                    else if(pos<p2) ans1+=abs(pos-p2)*v1;
                    ans=min(ans,ans1);
                }
                else //车在后面
                {
                    int ans1=abs(pos-p2)*v1;
                    ans=min(ans1,ans);
                }
            }
            else //反向;
            {
                if(pos>=p1)
                {
                    int ans1=2*pos*v1;
                    if(p2>pos) ans1+=abs(pos-p2)*v1;
                    else if(p2<pos) ans1-=abs(pos-p2)*v1;
                    ans=min(ans,ans1);
                }
                else
                {
                    int ans1=2*pos*v1;
                    ans1+=(p2-pos)*v1;
                    ans=min(ans,ans1);
                }
            }
        }
        else //p1>p2
        {
            if(d==-1)//同向;
            {
                if(pos<p1)
                {
                    int ans1=2*s*v1;
                    if(pos>p2) ans1+=abs(p2-pos)*v1;
                    else if(pos<p2) ans1-=abs(p2-pos)*v1;
                    ans=min(ans1,ans);
                }
                else
                {
                    int ans1=abs(pos-p2)*v1;
                    ans=min(ans1,ans);
                }
            }
            else //反向
            {
                if(pos<=p1)
                {
                    int ans1=2*abs(pos-s)*v1;
                    if(pos>p2) ans1+=abs(pos-p2)*v1;
                    else ans1-=abs(pos-p2)*v1;
                    ans=min(ans,ans1);
                }
                else
                {
                    int ans1=2*abs(pos-s)*v1;
                    ans1+=abs(pos-p2)*v1;
                    ans=min(ans,ans1);
                }
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

//100 20 83
//186 434
//64 -1
//27342


                                                 D. Green and Black Tea

   原来跟榜是有道理的,很多人C题和我想的一样复杂化了然后直接把D题做了。

   题意:小明要和a+b杯茶共n杯,有绿茶a杯,黑茶b杯。小明喝同一种茶最多连续喝k杯。问是否存在一种方案使得小明喝完这n杯茶,是则输出任意一种顺序。

   思路:没什么技巧,纯模拟。先考虑存在的情况,即max(a,b)-min(a,b)*k<=k。反之不存在。但千万注意min(a,b)*k会爆ll,博主就是这里没考虑到终判跪在第50组了。错失一波涨分的良机啊。

const int INF=0x3f3f3f3f;
const int N=1e6+7;
int a[N],v[N];
char s[N];
int main()
{
    int n,k,a,b,x,y;
    while(~scanf("%d%d%d%d",&n,&k,&a,&b))
    {
        if(a==b)
        {
            while(a--) printf("GB");
            printf("\n");
            continue;
        }
        x=max(a,b);
        y=min(a,b);
        if(x-y*k>k)//y*k会爆int
        {
            printf("NO\n");
            continue;
        }
        if(x<=k)
        {
            for(int i=1; i<=a; i++) printf("G");
            for(int i=1; i<=b; i++) printf("B");
            printf("\n");
        }
        else
        {
            if(a>b)//G更多
            {
                int kk=0;
                if(b-a/k<=0)
                {
                    for(int i=1; i<=a; i++)
                    {
                        printf("G");
                        kk++;
                        if(kk==k&&b)
                        {
                            printf("B");
                            kk=0;
                            b--;
                        }
                    }
                    printf("\n");
                }
                else
                {
                    b-=a/k;
                    for(int i=1; i<=a; i++)
                    {
                        printf("G");
                        kk++;
                        if(kk==k)
                        {
                            printf("B");
                            kk=0;
                            continue;
                        }
                        if(b)
                        {
                            printf("B");
                            b--;
                        }
                    }
                    printf("\n");
                }
            }
            else  //B更多;
            {
                int kk=0;
                if(a-b/k<=0)
                {
                    for(int i=1; i<=b; i++)
                    {
                        printf("B");
                        kk++;
                        if(kk==k&&a)
                        {
                            printf("G");
                            kk=0;
                            a--;
                        }
                    }
                    printf("\n");
                }
                else
                {
                    a-=b/k;
                    for(int i=1; i<=b; i++)
                    {
                        printf("B");
                        kk++;
                        if(kk==k)
                        {
                            printf("G");
                            kk=0;
                            continue;
                        }
                        if(a)
                        {
                            printf("G");
                            a--;
                        }
                    }
                    printf("\n");
                }
            }
        }
    }
    return 0;
}

这场比赛真心不难,时间又恰到好处。大概很多人平时做题都不会往后看,其实后面的题思路理清了并不难。这场B题开始看错题了,以为是求密文,原来是根据密文推出明文。最后0:39的时候做出来了,思维还是有点不够快。C题想了一会感觉很麻烦直接跳过看D题了,发现D题做的人更多,原来也是水题,考虑了一下代码就出来了,有个地方没注意WA了一发后改正初判过了。回来看C题发现就两种情况,写完时间不够了。就靠着这场咸鱼翻身,结果D题终判跪了,,原来有个地方会爆int...我竟无言以对。。真想给自己两巴掌!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值