首页 > 代码库 > Codeforces Round #379 (Div. 2) 解题报告

Codeforces Round #379 (Div. 2) 解题报告

题目地址

本次CF是在今天早上深夜进行,上午有课就没有直接参加。今天早上上课坐到后排参加了virtual participation。这次CF前面的题目都非常的水,不到10分钟就轻松过了前两题,比较郁闷的是之后一直卡在C,开始是脑残的没有用二分TLE,后来又是因为一个常数打错而一直WA……于是模拟赛就只过了2道题(太弱了orz)。时间到了后很快发现了脑残错误,终于A了C题。下午上完课回到宿舍看D题才发现D题水的不行,很快就A了。不过E和F就比较超出我现在知识范围了,暂时就先放下。第一次参加virtual participation,感觉这个模式真的是很赞,以后有时间一定要多多的参加训练自己。道阻且长,加油吧!

A题

这……就数一下A和D的个数,判断一下输出就可以了。没什么可说的。

技术分享
 1 #include <iostream>
 2 #include <cstdio>
 3 using namespace std;
 4 char a[100005];
 5 int n,m=0,k=0,i;
 6 int main()
 7 {
 8     scanf("%d",&n);
 9     scanf("%s",a);
10     for(i=0;i<n;i++)
11     {
12         if(a[i]==A)
13             m++;
14         else
15             k++;
16     }
17     if(m==k)
18         printf("Friendship\n");
19     else if(m>k)
20         printf("Anton\n");
21     else
22         printf("Danik\n");
23     return 0;
24 }
View Code

B题

先尽可能组256,2、5、6个数的最小值即为可组成的256个数。2减去256个数后再取2、3个数最小值即为32个数最大值。这样相加即得到了最多的个数。

技术分享
 1 #include <iostream>
 2 #include <cstdio>
 3 using namespace std;
 4 unsigned long long int a2,a3,a5,a6,he,de;
 5 unsigned long long min3(unsigned long long int x,unsigned long long int y,unsigned long long int z)
 6 {
 7     if(x<y)
 8         return min(x,z);
 9     else
10         return min(y,z);
11 }
12 int main()
13 {
14 cin>>a2>>a3>>a5>>a6;
15     de=min3(a2,a5,a6);
16     a2-=de;a5-=de;
17     a6-=de;
18     he+=de*256;
19     he+=min(a2,a3)*32;
20 cout<<he;
21 }
View Code

C题

(TLE、WA了很久,捂脸つ﹏?……)对于第一种魔法就是for循环,逐个判断,其中循环的内部二分查找此时第二种魔法可行中最好的一个。找到对于每一个第一种魔法的第二种魔法最优选法。注意还要看只选第二种魔法的情况。全都比较一下就找到了耗时最短的办法。

技术分享
 1 #include <iostream>
 2 #include <cstdio>
 3 using namespace std;
 4 unsigned long long int n,m,k,a[200002],b[200002],c[200002],d[200002],x,s,i,j,l,r,mid,an;
 5 int main()
 6 {
 7     cin>>n>>m>>k;
 8     cin>>x>>s;
 9     for(i=1;i<=m;i++)
10     cin>>a[i];
11     for(i=1;i<=m;i++)
12     cin>>b[i];
13     for(i=1;i<=k;i++)
14     cin>>c[i];
15     for(i=1;i<=k;i++)
16     cin>>d[i];
17     b[0]=c[0]=d[0]=0;
18     a[0]=x;
19     an=x*n;
20     for(i=0;i<=m;i++)
21     {
22         if(a[i]>x||b[i]>s)
23             continue;
24         l=1;r=k;
25         j=0;
26         while(l<=r)
27         {
28             mid=(l+r)>>1;
29             if(d[mid]+b[i]>s)
30                 r=mid-1;
31         else
32             {
33             l=mid+1;
34             j=max(mid,j);
35             }
36         }
37                 an=min(an,(n-c[j])*a[i]);
38     }
39     cout<<an;
40     return 0;
41 }
View Code

D题

用a数组记录8个方向是否可行,b数组记录此时各个方向离目标点最近的点的距离。全都进行过判断后,再遍历一遍a数组看是否有方向满足即可。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
long long int a[10],b[10],si,sj,ti,tj,n,st,kind,di;
int dir[3][10]={{1,1,1,1,1,1,1,1},{0,1,0,1,0,1,0,1},{1,0,1,0,1,0,1,0}},i;
char c[10];
int val(long int x,long long int y)
{
    long long int d1,d2;
    d1=x-si;
    d2=y-sj;
    if(d2==0&&d1<0)
        return 0;
    else if(d1+d2==0&&d2>0)
        return 1;
    else if(d1==0&&d2>0)
        return 2;
    else if(d1>0&&d1==d2)
        return 3;
    else if(d1>0&&d2==0)
        return 4;
    else if(d1>0&&d1+d2==0)
        return 5;
    else if(d1==0&&d2<0)
        return 6;
    else if(d1<0&&d2==d1)
        return 7;
    else return -1;
}
int main()
{
    memset(b,-1,sizeof(b));
    memset(a,0,sizeof(a));
    scanf("%I64d",&n);
    scanf("%I64d%I64d",&si,&sj);
    while(n--)
    {
        scanf("%s%I64d%I64d",c,&ti,&tj);
        if(c[0]==Q)
            kind=0;
        else if(c[0]==B)
            kind=1;
        else kind=2;
        st=val(ti,tj);
        if(st>-1)
        {
            di=max(abs(ti-si),abs(tj-sj));
            if(!dir[kind][st])
                {
                    if(di<b[st]||b[st]<0)
                        {b[st]=di;
                        a[st]=0;
                        }
                    continue;
                }
            else{
            if(di<b[st]||b[st]==-1)
                {
                    a[st]=1;
                    b[st]=di;
                }
            }
        }
        else
        {
            continue;
        }
    }
    for(i=0;i<8;i++)
    {
        if(a[i]==1)
            break;
    }
    if(i<8)
        printf("YES\n");
    else printf("NO\n");
}

 

Codeforces Round #379 (Div. 2) 解题报告