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

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

好遗憾没参加这场比赛……vp取得了目前最高的名次orz

A. Anastasia and pebbles

向上取整处理即可。

技术分享
 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <cstdio>
 6 #include <cmath>
 7 typedef long long ll;
 8 typedef unsigned long long ull;
 9 using namespace std;
10 const int MAX=1e5+5;
11 int n,k;
12 int w[MAX];
13 int qu(int x,int y)
14 {
15     return (x+y-1)/y;
16 }
17 int main()
18 {
19     scanf("%d%d",&n,&k);
20     for(int i=1;i<=n;i++)
21         scanf("%d",&w[i]);
22     ll an=0;
23     for(int i=1;i<=n;i++)
24     {
25         an+=qu(w[i],k);
26     }
27     an=qu(an,2);
28     cout<<an<<"\n";
29     return 0;
30 }
View Code

B.Masha and geometric depression

其实就限定一下最多求等比数列前多少项一直while就可以判断出答案(看比赛时好像这道题卡住了不少人orz)

技术分享
 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <cstdio>
 6 #include <cmath>
 7 typedef long long ll;
 8 typedef unsigned long long ull;
 9 using namespace std;
10 const int MAX=1e5+5;
11 int bad[MAX];
12 ll b1,q,l,m;
13 bool find(int x)
14 {
15     int l=1,r=m;
16     while(l<=r)
17     {
18         int mid=(l+r)>>1;
19         if(bad[mid]==x)
20             return true;
21         else if(bad[mid]>x)
22             r=mid-1;
23         else
24             l=mid+1;
25     }
26     return false;
27 }
28 int cnt=0;
29 ll an;
30 int main()
31 {
32     cin>>b1>>q>>l>>m;
33 //    scanf("%d%d%d%d",&b1,&q,&l,&m);
34     for(int i=1;i<=m;i++)
35         scanf("%d",&bad[i]);
36     sort(bad+1,bad+1+m);
37     ll now=b1;
38     while(abs(now)<=l&&cnt<=200000)
39     {
40         if(!find(now))
41         {
42             an++;
43         }
44         now*=q;
45         cnt++;
46     }
47     if(cnt==200001&&an>=100000)
48         printf("inf\n");
49     else
50         cout<<an<<"\n";
51     return 0;
52 }
View Code

C.Functions again

将读入的数组处理成相邻两数的差的绝对值之后就可以将其扔掉了。

动态规划,da[i][j] 如果j=0表示如果到第i个数(处理之后的,下同),取+时的最大值,如果j=1表示如果到第i个数(处理之后的,下同),取-时的最大值

xiao[i][j]如果j=0表示如果到第i个数(处理之后的,下同),取+时的最小值,如果j=1表示如果到第i个数(处理之后的,下同),取-时的最小值

下面用c[i]表示处理后的数组下标均从1开始

da[i][0]=max(c[i],da[i-1][1]+c[i])

da[i][1]=da[i-1][0]-c[i]

xiao[i][0]=min(c[i],xiao[i-1][1]+c[i])

xiao[i][1]=xiao[i-1][0]-c[i]

技术分享
 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <cstdio>
 6 #include <cmath>
 7 typedef long long ll;
 8 typedef unsigned long long ull;
 9 using namespace std;
10 const int MAX=1e5+5;
11 int a[MAX];
12 ll c[MAX];
13 ll da[MAX][2],xiao[MAX][2];
14 int n;
15 ll an;
16 int main()
17 {
18     scanf("%d",&n);
19     for(int i=1;i<=n;i++)
20         scanf("%d",&a[i]);
21     for(int i=1;i<n;i++)
22         c[i]=(ll)abs((ll)a[i+1]-(ll)a[i]);
23     da[1][0]=c[1];
24     an=c[1];
25     da[1][1]=0;
26     xiao[1][0]=c[1];
27     xiao[1][1]=0;
28     for(int i=2;i<n;i++)
29     {
30         da[i][0]=max(c[i],da[i-1][1]+c[i]);
31         da[i][1]=da[i-1][0]-c[i];
32         xiao[i][0]=min(c[i],xiao[i-1][1]+c[i]);
33         xiao[i][1]=xiao[i-1][0]-c[i];
34         an=max(an,da[i][0]);
35         an=max(an,da[i][1]);
36     }
37     cout<<an<<"\n";
38     return 0;
39 }
View Code

D.(还不会欧拉路orz……)

E.The Great Mixing

注意到数的范围其实非常小……考虑与n的差值,bfs搜索使和与n无相对差即可(比较坑的是k可以非常大,有可能有许多重复的数,所以还是1——1000挨个数看吧)

技术分享
 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <cstdio>
 6 #include <cmath>
 7 #include <queue>
 8 typedef long long ll;
 9 typedef unsigned long long ull;
10 using namespace std;
11 const int MAX=2e3+5;
12 const int INF=1e6;
13 bool an[MAX];
14 int vi[MAX];
15 queue<int> que;
16 int n,k;
17 int tem;
18 int main()
19 {
20     scanf("%d%d",&n,&k);
21     fill(vi,vi+2002,INF);
22     for(int i=1;i<=k;i++)
23     {
24         scanf("%d",&tem);
25         an[tem]=true;
26     }
27     vi[1000]=0;
28     que.push(1000);
29     while(!que.empty())
30     {
31         tem=que.front();que.pop();
32         for(int i=0;i<=1000;i++)
33         {
34             if(!an[i])
35                 continue;
36             int he=i+tem-n;
37             if(he<0||he>2000)
38                 continue;
39             else
40             {
41                 if(he==1000)
42                 {
43                     printf("%d\n",vi[tem]+1);return 0;
44                 }
45                 else if(vi[he]==INF)
46                 {
47                     vi[he]=vi[tem]+1;
48                     que.push(he);
49                 }
50             }
51         }
52     }
53     printf("-1\n");
54     return 0;
55 }
View Code

 

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