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

第一次全程参加的CF比赛(虽然过了D题之后就开始干别的去了),人生第一次codeforces上分……(或许之前的比赛如果都参加全程也不会那么惨吧),终于回到了specialist的行列,感动~。虽然最后也只过了A、B、D3题,但能上分还是非常的激动不已呀。

先发出来A、B、D的参考解法,C比赛时读了题感觉自己可以做出来,但时间只剩20分钟了,索性弃疗……。

11.23 补充上了C的参考代码

A题:

题目地址

用一些str函数应该也可以做,但考虑到字符串长度只有不到100以及题目整体不是很复杂,不如直接求解。

从头开始扫描,寻找为“ogo”的子串(注意扫到倒数第三个数就结束),如果扫到了那么就输出”***“并继续看“go"能重复多少个,这个过程都只用while循环控制一下就可以了。最后再从最后的位置到n用for循环(如果此时已经到头了那么for循环也不会也不需要进行了)

 1 #include<stdio.h>
 2 #include<bits/stdc++.h>
 3 #include <iostream>
 4 using namespace std;
 5 char a[106];
 6 int n,i=0;
 7 bool check()
 8 {
 9     if(a[i]=='o'&&a[i+1]=='g'&&a[i+2]=='o')
10         return true;
11     return false;
12 }
13 int main()
14 {
15 
16     scanf("%d",&n);
17     scanf("%s",a);
18 while(i<=n-3)
19     {
20         if(check())
21             {
22                 i+=3;
23             while(a[i]=='g'&&a[i+1]=='o')
24                 i+=2;
25             printf("***");
26             }
27         else
28         {
29             printf("%c",a[i]);
30             i++;
31         }
32     }
33     for(int j=i;j<n;j++)
34         printf("%c",a[j]);
35     return 0;
36 }

B题:

题目地址

只需要看从每个1能没有阻挡的直走到多少个0,将这些加起来即为所求的答案。所以扫一遍整个图,从每个1出发,向四周走,遇到1或走到边界停下,不然个数就+1。

 1 #include<stdio.h>
 2 #include<bits/stdc++.h>
 3 #include <iostream>
 4 using namespace std;
 5 int n,m,an,ii,jj;
 6 int lo[2000][2000],dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
 7 int main()
 8 {
 9     int i,j,k;
10     scanf("%d%d",&n,&m);
11     an=0;
12     for(int i=1;i<=n;i++)
13     {
14         for(int j=1;j<=m;j++)
15             scanf("%d",&lo[i][j]);
16     }
17     for(i=1;i<=n;i++)
18     {
19         for(j=1;j<=m;j++)
20         {
21             if(lo[i][j]==1)
22             {
23                 for(k=0;k<4;k++)
24                 {
25                         ii=i;
26                         jj=j;
27                     while((ii>0&&ii<=n&&jj>0&&jj<=m&&lo[ii][jj]==0)||(ii==i&&jj==j))
28                     {
29                         ii+=dir[k][0];
30                         jj+=dir[k][1];
31                         if(ii>0&&ii<=n&&jj>0&&jj<=m&&lo[ii][jj]==0)
32                             {an+=1;
33                             }
34                         else break;
35                     }
36                 }
37             }
38         }
39     }
40     printf("%d\n",an);
41     return 0;
42 }

C题

二分查找,先按汽车油箱容量递增排序,二分查找符合条件的油箱最小容量。再排序,找最低的价格。初始设定答案为一个很大的数,如果最后答案不变输出-1,不然输出新的最小价格。

题目地址

 1 #include<stdio.h>
 2 #include<bits/stdc++.h>
 3 #include <iostream>
 4 using namespace std;
 5 long long int k,n,x=0,dis[200005];
 6 long long int s,t,time1,an,l,r,mid;
 7 bool cmp(long long x,long long y)
 8 {
 9     return x<y;
10 }
11 struct oh
12 {
13     long long cap,val;
14 }che[200005];
15 bool cmp2(oh x,oh y)
16 {
17     if(x.cap!=y.cap)
18         return x.cap<y.cap;
19     else
20         return x.val<y.val;
21 }
22 bool cmp3(oh x,oh y)
23 {
24     return x.val>y.val;
25 }
26 int main()
27 {
28     scanf("%I64d%I64d%I64d%I64d",&n,&k,&s,&t);
29     long long int i,j;
30     dis[0]=0;
31     an=20000000005;
32     for(i=1;i<=n;i++)
33     {
34         scanf("%I64d%I64d",&che[i].val,&che[i].cap);
35     }
36     for(i=1;i<=k;i++)
37     {
38         scanf("%I64d",&dis[i]);
39     }
40     sort(dis+1,dis+k+1,cmp);
41     sort(che+1,che+n+1,cmp2);
42     dis[k+1]=s;
43     time1=0;
44     l=1;r=n;
45     while(l<=r)
46     {
47         mid=(l+r)/2;
48         for(j=1;j<=k+1;j++)
49         {
50             if(dis[j]-dis[j-1]>che[mid].cap)
51                 break;
52             else
53             {
54                 if(x<che[mid].cap-2*(dis[j]-dis[j-1]))
55                     time1+=(dis[j]-dis[j-1]-x);
56                 else
57                     time1+=(3*(dis[j]-dis[j-1])-che[mid].cap);
58             }
59         }
60         if(j==k+2&&time1<=t)
61         {
62             r=mid-1;
63         }
64         else
65         {
66             l=mid+1;
67         }
68         time1=0;
69     }
70 if(r<n)
71     {sort(che+r+1,che+n+1,cmp3);
72     printf("%I64d\n",che[n].val);}
73     else
74         printf("-1\n");
75 return 0;
76 }

 

D题

题目地址

我的做法貌似有点麻烦。对整个字符串现在前面加上1,末尾加上1,之后扫描一遍,对于连续的0长度小于船长的部分直接填上1。并用he代表余下为0的个数,最少的操作数即为通过最少的操作达到he<船长*船个数的状态。(注意到射击1个1右面数第”船长“个0如果没有打中船,那么从这个1到那个位置之间所有的都一定不会是船的一部分)这样之后从左往右扫,遇到a[i]=1,a[i+1]=0就意味着从第i个数开始一定有不小于船长个连续的0,这样对其操作一定不会产生”浪费“,一定会是最优的操作。如果是1而下个数不是0,那么就是碰上连续1的情况,i++即可,如果是0的话,he--,继续扫描,注意要用一个计数变量记录连续这样的0有多少个,如果达到船长就意味着有必要进行一次操作,以求达到最优的解法。

#include<stdio.h>
#include<bits/stdc++.h>
#include <iostream>
using namespace std;
char a[200030];
int n,ge,len,st,en,i,j,he=0,k,cnt=0,an[200030],s,geshu,chang;
int main()
{
    scanf("%d%d%d%d",&n,&ge,&len,&k);
    a[0]='1';
    scanf("%s",a+1);
    a[n+1]='1';
    st=0;en=0;
he=n-k;
    for(i=1;i<=n+1;i++)
    {
        if(a[i]=='1')
        {
            en=i;
            if(en-st-1>0&&en-st-1<len)
                {for(i=st+1;i<en;i++)
                    a[i]='1';
                he-=(en-st-1);
                }
            else
                if((en-st-1)%len!=0)
            {
                for(j=en-1;j>=en-(en-st-1)%len;j--)
                    {a[j]='1';
                    he--;
                    }
            }
                st=i;
        }
    }
    chang=len*ge;
    i=0;
    while(he>=chang)
    {
        if(a[i]=='1'&&a[i+1]=='0')
        {
            geshu=0;
            an[cnt]=i+len;
            cnt++;
            for(j=i+1;j<=i+len;j++)
            {
                a[j]='1';
            }
            he-=len;
            i=i+len;
        }
        else{
    if(a[i]=='1')
        {
            geshu=0;
            while(a[i]!='0')
                i++;
            i--;
        }
    else
    {
        if(geshu<len-1)
        {
            a[i]='1';
            geshu++;
            he--;
        }
        else
        {
            he--;
            geshu=0;
            a[i]='1';
            an[cnt]=i;
            cnt++;
        }
    }
        }
    }
    printf("%d\n",cnt);
    for(i=0;i<cnt;i++)
        printf("%d ",an[i]);
        return 0;
}

通过这次CF,发现或许自己没有自己之前想象的那么水,以后再参加比赛一定好好对待,全程参加,不再划水了。

posted @ 2016-11-20 21:34  perplex  阅读(261)  评论(0编辑  收藏  举报