Codeforces Round #372 +#373 部分题解

Posted New_Godess

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #372 +#373 部分题解相关的知识,希望对你有一定的参考价值。

用了两场比赛上Div 1感觉自己好腊鸡的说。。。以下是这两场比赛的部分题解(不得不说有个黄学长来抱大腿还是非常爽的)

Round #372 :

Div 2 A:Crazy Computer

题意:给定N个输入和一个时间长度M,每次输入屏幕上增加一个字符,若两个输入间隔大于M则屏幕上的字符会被清空,问结束时屏幕上还有多少个字符

直接模拟没有什么好说的

代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 int main(){
 7     int n,c;
 8     scanf("%d%d",&n,&c);
 9     int last=0,cnt=0;
10     for (int i=1;i<=n;i++) {
11         int x;
12         scanf("%d",&x);
13         if (x-last>c) cnt=0;
14         last=x;cnt++;
15     }
16     printf("%d\\n",cnt);
17     return 0;
18 }
Crazy Computer
 Div 2 B:Complete the Word 

题意:给定一个字符串,其中某些字符未知,要求给出一个可能的字符串,使得存在一个包含26个大写字母的长度为26的连续子串

这题也是直接乱搞吧大概,我的思路就是统计每个子串中是否有重复,没有就说明合理然后随便构造一个答案就行了

代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 char s[50100];
 7 int a[30],n;
 8 int cnt=0;
 9 int main(){
10     scanf("%s",s+1);
11     int n=strlen(s+1);
12     int l=1;
13     int cnt=0;
14     for (int i=1;i<=n;i++){
15         if (s[i]==\'?\') {
16             cnt++;
17         }else {
18             int t=s[i]-\'A\'+1;
19             if (a[t]==1) {
20                 while (s[i]!=s[l]) {
21                     if (s[l]==\'?\') {
22                         cnt--;
23                     }else a[s[l]-\'A\'+1]--;
24                     l++;
25                 }
26                 if (s[l]==\'?\') cnt--;
27                 else a[s[l]-\'A\'+1]--;
28                 l++;
29             }
30             a[t]++;
31         }
32         if (i-l+1==26) {
33             for (int j=1;j<l;j++) printf("%c",s[j]==\'?\'?\'A\':s[j]);
34             for (int j=l;j<=i;j++) {
35                 if (s[j]!=\'?\') printf("%c",s[j]);
36                 else {
37                     for (int k=1;k<=26;k++) {
38                         if (a[k]) continue;
39                         printf("%c",k+\'A\'-1);
40                         a[k]++;
41                         break;
42                     }
43                 }
44             }
45             for (int j=i+1;j<=n;j++) printf("%c",s[j]==\'?\'?\'A\':s[j]);
46             return 0;
47         }
48     }
49     printf("-1\\n");
50     return 0;
51 }
Complete the Word

Div 2 C and Div 1 A:Plus and Square Root

题意:给定一个数和两个操作,一个操作为+k,另一个操作为开根号然后k=k+1,初始时数为1,k=1,求达到k=n+1时的操作数

考虑构造一个可行方案,设执行开方操作后那个数为t,那么有$t=mk,m\\in \\mathbb N$(若不满足则下一次无法开方)同时考虑开方操作前有$t^2=n(k-1),n \\in \\mathbb N$所以令$t=k(k-1)$ 即可

代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 typedef long long ll;
 7 ll n,x;
 8 int main(){
 9 cin>>n;
10 x=2;
11 for (ll i=1;i<=n;i++) {
12     ll ans=(i+1)*(i+1)*i-x/i;
13     cout<<ans<<endl;
14     x=i*(i+1);
15 }
16 
17 }
Plus and Square Root

Div 2 D and Div 1 B:Complete The Graph

题意:给定一张图,其中某些边的长度未知,求是否存在一种方案,使得最短路为L

先分层建图,求出经过k条未知边的最短路,然后从经过未知边数从小到大开始处理,直接构造出经过k条未知边,最短路为L的路径,可以得出,若无法构造出小于k条未知边的最短路为L的路径,那么该构造方式不会出现更短的路径。

这道题在考试时没秒出来,考完才发现写成大根堆+构图构太大MLE了囧。。。(不然说不定一场DIV 1了哼~)

代码:

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<queue>
  6 using namespace std;
  7 typedef long long ll;
  8 typedef pair<int,int>ii;
  9 typedef pair<ll,ii> iii;
 10 #define maxn 1001000
 11 #define maxm 20100
 12 #define se second
 13 struct edges{
 14     int to,next;ll dis;int b;
 15 }edge[maxm];
 16 int id[1010][1010];
 17 int nxt[maxn],l;
 18 inline void addedge(int x,int y,ll z,int b) {
 19     edge[++l]=(edges){y,nxt[x],z,b};nxt[x]=l;
 20 }
 21 #define INF 0x7fffffff
 22 #define MAXINF INF*1ll*INF
 23 #define fi first
 24 #define inf 10000000000000ll
 25 int clo=0;
 26 int f[maxn],e[maxn];
 27 ll dis[maxn];
 28 bool b[maxn];
 29 int n;
 30 inline void dij(int x,int y) {
 31     for (int i=1;i<=clo;i++) dis[i]=MAXINF;
 32     dis[id[x][y]]=0;
 33     static priority_queue<iii,vector<iii>,greater<iii> > q;
 34     q.push(iii(0,ii(x,y)));
 35     while (!q.empty()){
 36         iii x=q.top();q.pop();
 37         int u=x.se.fi,v=x.se.se;
 38         if (b[id[u][v]]) continue;
 39         b[id[u][v]]=1;
 40         for (int i=nxt[u];i;i=edge[i].next){
 41             ii t;
 42             if (edge[i].dis==inf) t=ii(edge[i].to,v+1);
 43             else t=ii(edge[i].to,v);
 44             if (edge[i].dis==inf&& v==n-1) continue;
 45             if (dis[id[t.fi][t.se]]>dis[id[u][v]]+edge[i].dis) {
 46                 dis[id[t.fi][t.se]]=dis[id[u][v]]+edge[i].dis;
 47                 f[id[t.fi][t.se]]=id[u][v];e[id[t.fi][t.se]]=i;
 48                 q.push(iii(dis[id[t.fi][t.se]],t));
 49             }
 50         }
 51     }
 52     return ;
 53 }
 54 #define M 10010
 55 #define N 1010
 56 int x[M],y[M];
 57 ll w[M];
 58 int m,s,t;
 59 int main(){
 60     ll l;
 61     scanf("%d%d%I64d%d%d",&n,&m,&l,&s,&t);
 62     s++;t++;
 63     for (int i=1;i<=n;i++) 
 64         for (int j=0;j<n;j++) id[i][j]=++clo;
 65     for (int i=1;i<=m;i++) {
 66         scanf("%d%d%I64d",x+i,y+i,w+i);
 67         x[i]++;y[i]++;
 68         if (w[i]==0){ 
 69                 addedge(x[i],y[i],inf,i);
 70                 addedge(y[i],x[i],inf,i);
 71             }
 72         else {
 73                 addedge(x[i],y[i],w[i],i);
 74                 addedge(y[i],x[i],w[i],i);
 75         }
 76     }
 77     dij(s,0);
 78         if (dis[id[t][0]]<l) {
 79             printf("NO\\n");
 80             return 0;
 81         }
 82     for (int i=0;i<n;i++) {
 83         if (dis[id[t][i]]==MAXINF) continue;
 84         if (dis[id[t][i]]%inf>l-i) continue;
 85         printf("YES\\n");
 86         int u=id[t][i],tmp=l-dis[id[t][i]]%inf;
 87         int cnt=0;
 88         while (u!=id[s][0]) {
 89             if (edge[e[u]].dis==inf) {
 90                 cnt++;
 91                 if (cnt==i) w[edge[e[u]].b]=tmp;
 92                 else {
 93                     w[edge[e[u]].b]=1;
 94                     tmp--;
 95                 }
 96             }
 97             u=f[u];
 98         }
 99         for (int i=1;i<=m;i++) printf("%d %d %I64d\\n",x[i]-1,y[i]-1,w[i]?w[i]:inf);
100         return 0;
101     }
102     printf("NO\\n");
103     return 0;
104 }
Complete The Graph

Round #373 :

这一场好像数据出了好多错结果Div 1 unrated了。。。。不过还好Div 2没死然后自己就上Div 1辣(开心),黄学长也因此逃过了掉rate的命运。。。

Div 2 A:Vitya in the Countryside

题意:给定一个月亮阴晴圆缺的序列,求判断接下来月亮是变圆还是变缺

直接判断序列是上升还是下降即可,注意0和15即可

代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 int n,a[1000];
 7 int main(){
 8     scanf("%d",&n);
 9     for (int i=1;i<=n;i++) scanf("%d",a+i);
10     if (a[n]==0) {
11         printf("UP\\n");
12         return 0;
13     }
14     if (a[n]==15) {
15         printf("DOWN\\n");
16         return 0;
17     }
18     if (n==1) {
19         printf("-1\\n");
20         return 0;
21     }
22     if (a[n-1]<a[n]) printf("UP\\n");
23     else printf("DOWN\\n");
24     return 0;
25 }
Vitya in the Countryside

Div 2 B:Anatoly and Cockroaches

题意:给定一串珠子,有两种操作:给一个珠子涂色,交换2个珠子位置,求使这串珠子黑白相间的最小操作

分黑白黑白黑和白黑白黑白考虑咯,然后每次只判断奇位或偶位,看是不是那种颜色,如果不是再考虑要涂色还是交换(有点口胡写的代码也很挫。。。)

代码:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<iostream>
 5 using namespace std;
 6 int n,ans,tmp,cnt,sum;
 7 char s[100100];
 8 int main(){
 9     scanf("%d",&n);
10     scanf("%s",s+1);
11     ans=0x7fffffff;
12     for (int i=1;i<=n;i++) if (s[i]==\'b\') cnt++;
13     tmp=n/2+n%2-cnt;
14         sum=0;
15         for (int i=1;i<=n;i++) 
16             if (i%2==1&&s[i]==\'r\') sum++ ;
17         if (tmp>=0){
18         ans=min(ans,max(tmp,sum));
19     }
20     tmp-=n%2;
21     if (tmp>=0) {
22     ans=min(ans,max(tmp,n-cnt-sum));
23     }
24     cnt=n-cnt;
25     tmp=n/2-cnt+n%2;
26     sum=0;
27     for (int i=1;i<=n;i++) 
28         if (i%2==1&&s[i]==\'b\') sum++;
29     if (tmp>=0) {
30     ans=min(ans,max(tmp,sum));
31     }
32     tmp-=n%2;
33     if (tmp>=0) { 
34     ans=min(ans,max(tmp,n-cnt-sum));
35     }
36 //    printf("%d %d %d %d\\n",tmp,sum,cnt,ans);
37     printf("%d\\n",ans);
38     return 0;
39 }
Anatoly and Cockraches

Div 2 C and Div 1 A Efim and Strange Grade

题意:给定一个浮点数,有n次四舍五入的机会,求获得最大的数大小

从高位到低位找到第一个大于5的数位进位即可,主要注意输出格式和进位问题就没了

代码:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<queue>
 6 using namespace std;
 7 typedef pair<int,int> ii;
 8 #define fi first
 9 #define se second
10 priority_queue<int,vector<int>,greater<int> > q;
11 int n,m,flag=0,cnt;
12 char s[200010];
13 int main(){
14     scanf("%d%d",&n,&m);
15     scanf("%s",s+1);
16     for (int i=1;i<=n;i++) {
17         if (s[i]==\'.\') {cnt=i;flag=1;continue;}
18         if (flag==1 && s[i]>\'4\') q.push(i);
19     }
20     if (!flag) {printf("%s\\n",s+1);return 0;}
21     flag=1;
22     int lst=n+1;
23     for (int i=1;i<=m;i++) {
24         if (q.empty()) break;
25         int u=q.top();q.pop();
26         if (u>lst ) break;
27         lst=u;
28         if (u==cnt+1) {
29             int t=u-2;
30             while (s[t]==\'9\') s[t]=\'0\',t--;
31             if (t==0) {flag=0;s[t]=\'1\';}
32             else s[t]++;
33         }
34         else {
35             s[u-1]++;
36             if (s[u-1]>\'4\') q.push(u-1);
37         }
38         s[u]=0;
39     }
40     int n=lst-1;
41     for (;s[n]==\'0\';n--); 
42     s[n+1]=0;
43     if (s[n]==\'.\') s[n]=0;
44     printf("%s\\n",s+flag);
45     return 0;
46 }
Efim and Strange Grade

Div 2 D and Div 1 B

虽然是一道错题不过解法还是挺机智的

题意:有N个复印机,每个复印机复印文件要ti秒,现在有m个任务,每个任务要求需要x个副本,求复印所需要的最小时间

先把  每个复印机投入工作的时间计算出来记为si,然后二分时间T,那么时间T内的副本数就为$\\sum_{i=1}^n \\lfloor \\frac{T-si}{ti} \\rfloor$但因为复印机数太多所以还是过不了,考虑到$1<=ti<=1000$ 那么就把复印时间相同的复印机放在一起处理

Div 2 E and Div 1 C Sasha and Array

题意:给定一个序列,支持区间加法和区间求其斐波那契数之和

线段树+矩阵乘法裸题,注意点优化就行了,例如lazy直接存斐波那契数的矩阵什么的就没问题了

以上是关于Codeforces Round #372 +#373 部分题解的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #805 (Div. 3) 题解

Codeforces Round #725 (Div. 3)Codeforces-1538

Educational Codeforces Round 7 A

Codeforces Round #617 (Div. 3)

Codeforces Round #515 (Div. 3)未完结

Codeforces Round #521 (Div. 3) + DP