CF604(div.2)
Posted njwsf
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF604(div.2)相关的知识,希望对你有一定的参考价值。
CF的模拟赛还是挺不错的,能完全模拟每一分钟的排名和提交。
听别人说一有时间就来一场模拟赛有助于提升水平,不过每场比赛的质量还是有很大区别的,但是我也不可能模拟之前就知道题目质量,所以我对这个看法还是有点怀疑。
A:
每次遇到‘?’,就随便找一个和它左右两边都不一样的字符代替,最后再按照限制扫一遍就行了。
代码:
1 #pragma GCC optimize("Ofast,unroll-loops") 2 #include<bits/stdc++.h> 3 #define ll long long 4 #define F first 5 #define S second 6 #define P pair 7 #define FOR(i,a,b) for(int i=a;i<=b;i++) 8 #define rep(i,a,b) for(int i=a;i<b;i++) 9 #define V vector 10 #define RE return 11 #define ALL(a) a.begin(),a.end() 12 #define MP make_pair 13 #define PB push_back 14 #define PF push_front 15 #define FILL(a,b) memset(a,b,sizeof(a)) 16 using namespace std; 17 void solve(){ 18 string s; 19 cin>>s; 20 s="?"+s+"?"; 21 rep(i,1,s.size()-1){ 22 if(s[i]!=‘?‘)continue; 23 if(s[i-1]!=‘a‘&&s[i+1]!=‘a‘){ 24 s[i]=‘a‘; 25 }else if(s[i-1]!=‘b‘&&s[i+1]!=‘b‘){ 26 s[i]=‘b‘; 27 }else if(s[i-1]!=‘c‘&&s[i+1]!=‘c‘){ 28 s[i]=‘c‘; 29 } 30 } 31 rep(i,1,s.size()-2){ 32 if(s[i]==s[i+1]){ 33 cout<<"-1 ";RE; 34 } 35 } 36 rep(i,1,s.size()-1)cout<<s[i]; 37 cout<<‘ ‘; 38 } 39 int main(){ 40 ios::sync_with_stdio(0); 41 cin.tie(0); 42 int t; 43 cin>>t; 44 while(t--)solve(); 45 RE 0; 46 }
B:
这题用双指针,上来先输出一个1,设定一个正确区域,先让正确区域的左右两端都定为1所在的位置。
从2开始,一个个处理。每有新的数加入,就让正确区域的范围成为包括这个数的最小区域,然后判断一下是不是正确区域的长度和到现在为止数的总数相等就行了。
代码:
1 #pragma GCC optimize("Ofast,unroll-loops") 2 #include<bits/stdc++.h> 3 #define ll long long 4 #define F first 5 #define S second 6 #define P pair 7 #define FOR(i,a,b) for(int i=a;i<=b;i++) 8 #define rep(i,a,b) for(int i=a;i<b;i++) 9 #define V vector 10 #define RE return 11 #define ALL(a) a.begin(),a.end() 12 #define MP make_pair 13 #define PB push_back 14 #define PF push_front 15 #define FILL(a,b) memset(a,b,sizeof(a)) 16 using namespace std; 17 int c[200005]; 18 void solve(){ 19 int n,x; 20 cin>>n; 21 FOR(i,1,n)c[i]=0; 22 FOR(i,1,n){ 23 cin>>x;c[x]=i; 24 } 25 cout<<1; 26 int l=c[1],r=l; 27 FOR(i,2,n){ 28 l=min(l,c[i]); 29 r=max(r,c[i]); 30 if(r-l+1==i){ 31 cout<<1; 32 }else cout<<0; 33 } 34 cout<<‘ ‘; 35 } 36 int main(){ 37 ios::sync_with_stdio(0); 38 cin.tie(0); 39 int t; 40 cin>>t; 41 while(t--)solve(); 42 RE 0; 43 }
C:
因为这里要求是让金牌比银牌分数高,银牌比铜牌分数高,铜牌比没拿牌的分数高,所以按题目给的序列分配奖牌应该是:金,银,铜,没有。
这里要求获奖人数最多,所以直接贪心取人就可以了,这样也不会影响其他条件。
直接让最高分当金牌,再一直往后分配银牌,一直到比金牌多,铜牌也是一样。
最后来一次检查就行了,代码:
1 #pragma GCC optimize("Ofast,unroll-loops") 2 #include<bits/stdc++.h> 3 #define ll long long 4 #define F first 5 #define S second 6 #define P pair 7 #define FOR(i,a,b) for(int i=a;i<=b;i++) 8 #define rep(i,a,b) for(int i=a;i<b;i++) 9 #define V vector 10 #define RE return 11 #define ALL(a) a.begin(),a.end() 12 #define MP make_pair 13 #define PB push_back 14 #define PF push_front 15 #define FILL(a,b) memset(a,b,sizeof(a)) 16 using namespace std; 17 V<P<int,int> > v; 18 void solve(){ 19 int n,x,last=-1,l; 20 v.clear(); 21 cin>>n; 22 FOR(i,1,n){ 23 cin>>x; 24 if(x!=last){ 25 if(i!=1){ 26 v.PB(MP(last,l)); 27 } 28 l=1;last=x; 29 }else l++; 30 } 31 v.PB(MP(last,l)); 32 int t=0,sum=0; 33 rep(i,0,v.size()){ 34 if(sum+v[i].S>n/2)break; 35 t++;sum+=v[i].S; 36 } 37 if(t<3){ 38 cout<<"0 0 0 ";RE; 39 } 40 int a,b,c; 41 a=v[0].S;b=c=0; 42 rep(i,1,t){ 43 if(b<=a)b+=v[i].S;else c+=v[i].S; 44 } 45 if(b<=a||c<=a){ 46 cout<<"0 0 0 "; 47 }else cout<<a<<‘ ‘<<b<<‘ ‘<<c<<‘ ‘; 48 } 49 int main(){ 50 ios::sync_with_stdio(0); 51 cin.tie(0); 52 int t; 53 cin>>t; 54 while(t--)solve(); 55 RE 0; 56 }
D:
这题就是CF用来磨人的吧,又不知道是哪位出的题,这题本来毫无难度,结果代码还很烦。
首先把答案序列分为3段:0-1,1-2,2-3.
这里前后两端是当做调整的,因为它们只需一边符合要求。
在正常情况下,只要b<a或c<d就不行,因为这样的话会让3段没法连接。
当然也有不正常的情况,只有1段:如果2种数字数量差小于2就直接交叉输出两种数字,否则就不行。
让1和0两种数字在中间先组合一下,直到再组合下去就小于0或3的数量了。
如果这时0和3的数量相差小于2,则可以通过前后的端点调整过来,否则不行。
代码:
1 #pragma GCC optimize("Ofast,unroll-loops") 2 #include<bits/stdc++.h> 3 #define ll long long 4 #define F first 5 #define S second 6 #define P pair 7 #define FOR(i,a,b) for(int i=a;i<=b;i++) 8 #define rep(i,a,b) for(int i=a;i<b;i++) 9 #define V vector 10 #define RE return 11 #define ALL(a) a.begin(),a.end() 12 #define MP make_pair 13 #define PB push_back 14 #define PF push_front 15 #define FILL(a,b) memset(a,b,sizeof(a)) 16 using namespace std; 17 int main(){ 18 ios::sync_with_stdio(0); 19 cin.tie(0); 20 int a,b,c,d; 21 cin>>a>>b>>c>>d; 22 if(a>b){ 23 if(a-b==1&&!c&&!d){ 24 cout<<"YES "; 25 FOR(i,1,b)cout<<"0 1 "; 26 cout<<0; 27 }else cout<<"NO"; 28 RE 0; 29 } 30 if(c<d){ 31 if(d-c==1&&!a&&!b){ 32 cout<<"YES "; 33 FOR(i,1,c)cout<<"3 2 "; 34 cout<<3; 35 }else cout<<"NO"; 36 RE 0; 37 } 38 b-=a;c-=d; 39 if(abs(b-c)>1){ 40 cout<<"NO";RE 0; 41 } 42 cout<<"YES "; 43 if(b>c)cout<<"1 "; 44 FOR(i,1,a)cout<<"0 1 "; 45 FOR(i,1,min(b,c))cout<<"2 1 "; 46 FOR(i,1,d)cout<<"2 3 "; 47 if(c>b)cout<<2; 48 RE 0; 49 }
E:
这题让我有点蒙,我看题目描述很简单。
其实我得出一个可能不太对的结论:CF的代码难度和题目长度有很大的关系,atcoder则几乎没有关系(F题和A题的题目长度一般没啥区别)。
这题的期望天数就是所有的100/pi(1<=i<=n),我是直接找到了规律。
后来我发现它的依据是:
设dp[i]表示到第i天的期望天数。
dp[i]=(dp[i-1]+1)*%pi+(dp[i-1]+1+dp[i])*(1-%pi)
这里学过概率的人肯定秒题,但是像我就只能找规律(其实也是秒题了)。
代码:
1 #pragma GCC optimize("Ofast,unroll-loops") 2 #include<bits/stdc++.h> 3 #define int long long 4 #define F first 5 #define S second 6 #define P pair 7 #define FOR(i,a,b) for(int i=a;i<=b;i++) 8 #define rep(i,a,b) for(int i=a;i<b;i++) 9 #define V vector 10 #define RE return 11 #define ALL(a) a.begin(),a.end() 12 #define MP make_pair 13 #define PB push_back 14 #define PF push_front 15 #define FILL(a,b) memset(a,b,sizeof(a)) 16 using namespace std; 17 int inv[105],x,mod=998244353; 18 signed main(){ 19 ios::sync_with_stdio(0); 20 cin.tie(0); 21 int n; 22 cin>>n; 23 inv[1]=1; 24 FOR(i,2,100)inv[i]=mod-inv[mod%i]*(mod/i)%mod; 25 int ans=0; 26 FOR(i,1,n){ 27 cin>>x; 28 ans=(ans+1)*100%mod*inv[x]%mod; 29 } 30 cout<<ans; 31 RE 0; 32 }
55名,希望我比赛时也能发挥这么好。
以上是关于CF604(div.2)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #604 (Div. 2) 练习A,B题解
Codeforces Round #604 (Div. 2) A. Beautiful String(贪心)
Codeforces Round #604 (Div. 2) B. Beautiful Numbers(双指针)
CF 604C Alternative Thinking#贪心