CF617(div.3)
Posted njwsf
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF617(div.3)相关的知识,希望对你有一定的参考价值。
昨天下午没啥事,就模拟了一场比赛。
这场div.3我居然最后只排到了200+,主要是刚好只给我18分钟做最后一题,然而我一下没反应过来,就没做出来(后来发现是水题)。
A:
如果全是偶数或序列长度是偶数且元素全是奇数那么输出“NO”,否则输出“YES”。
代码:
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 V vector 9 #define RE return 10 #define ALL(a) a.begin(),a.end() 11 #define MP make_pair 12 #define PB push_back 13 #define PF push_front 14 #define FILL(a,b) memset(a,b,sizeof(a)) 15 using namespace std; 16 int a[2005],n; 17 void solve(){ 18 cin>>n;bool f1,f2;f1=f2=0; 19 FOR(i,1,n){ 20 cin>>a[i];if(a[i]&1)f1=1;else f2=1; 21 } 22 if(!f1||(!(n&1)&&!f2)){ 23 cout<<"NO "; 24 }else cout<<"YES "; 25 } 26 int main(){ 27 ios::sync_with_stdio(0); 28 cin.tie(0); 29 int t; 30 cin>>t; 31 while(t--)solve(); 32 RE 0; 33 }
B:
就模拟加贪心,每次都让他买10元的物品,再用还回来的钱再买,一直到钱数小于10,再把剩下的钱用掉就可以了(我因为直接输出s/0.9WA了一次)。
代码:
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 V vector 9 #define RE return 10 #define ALL(a) a.begin(),a.end() 11 #define MP make_pair 12 #define PB push_back 13 #define PF push_front 14 #define FILL(a,b) memset(a,b,sizeof(a)) 15 using namespace std; 16 void solve(){ 17 int s; 18 cin>>s; 19 int ans=0,t; 20 while(s>=10){ 21 int t=s/10; 22 ans+=t*10;s-=t*9; 23 } 24 cout<<ans+s<<‘ ‘; 25 } 26 int main(){ 27 ios::sync_with_stdio(0); 28 cin.tie(0); 29 int t; 30 cin>>t; 31 while(t--)solve(); 32 RE 0; 33 }
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 V vector 9 #define RE return 10 #define ALL(a) a.begin(),a.end() 11 #define MP make_pair 12 #define PB push_back 13 #define PF push_front 14 #define FILL(a,b) memset(a,b,sizeof(a)) 15 using namespace std; 16 int n,a,b,h; 17 V<int> v; 18 int main(){ 19 ios::sync_with_stdio(0); 20 cin.tie(0); 21 int k; 22 cin>>n>>a>>b>>k; 23 int ans=0; 24 FOR(i,1,n){ 25 cin>>h; 26 h%=(a+b); 27 if(!h){ 28 v.PB(b); 29 }else if(h<=a){ 30 ans++; 31 }else{ 32 v.PB(h-a); 33 } 34 } 35 sort(ALL(v)); 36 for(int i=0;i<v.size();i++){ 37 int c=v[i]/a+(v[i]%a!=0); 38 if(c>k){ 39 break; 40 }else{ 41 k-=c; 42 ans++; 43 } 44 } 45 cout<<ans; 46 RE 0; 47 }
D:
可以先模拟一下,如果已经是我击败的就不用管了。
剩下的就是先算出在敌人完成击杀前怪兽的血量,再从小到大排序。因为怪兽血量越少,使用魔法的次数越少。
最后就直接顺着模拟下去,一直到魔法不够用了。
代码:
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 V vector 9 #define RE return 10 #define ALL(a) a.begin(),a.end() 11 #define MP make_pair 12 #define PB push_back 13 #define PF push_front 14 #define FILL(a,b) memset(a,b,sizeof(a)) 15 using namespace std; 16 int n,a,b,h; 17 V<int> v; 18 int main(){ 19 ios::sync_with_stdio(0); 20 cin.tie(0); 21 int k; 22 cin>>n>>a>>b>>k; 23 int ans=0; 24 FOR(i,1,n){ 25 cin>>h; 26 h%=(a+b); 27 if(!h){ 28 v.PB(b); 29 }else if(h<=a){ 30 ans++; 31 }else{ 32 v.PB(h-a); 33 } 34 } 35 sort(ALL(v)); 36 for(int i=0;i<v.size();i++){ 37 int c=v[i]/a+(v[i]%a!=0); 38 if(c>k){ 39 break; 40 }else{ 41 k-=c; 42 ans++; 43 } 44 } 45 cout<<ans; 46 RE 0; 47 }
E1:
其实这题不难发现如果一个字符它比在它前面的字符小时,那么这两个字符的值必定不同。
但是我注意到E1和E2并不是完全一样,所以我就直接先考虑这题了。
我建了一个图,一条连接a和b的边表示a和b颜色不同。
最后跑一边,如果矛盾输出-1,否则输出答案。
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 V vector 9 #define RE return 10 #define ALL(a) a.begin(),a.end() 11 #define MP make_pair 12 #define PB push_back 13 #define PF push_front 14 #define FILL(a,b) memset(a,b,sizeof(a)) 15 using namespace std; 16 V<int> v[205];int n; 17 string s; 18 int ans[205]; 19 void dfs(int p,int co){ 20 if(ans[p]){ 21 if(co!=ans[p]){ 22 cout<<"NO";exit(0); 23 } 24 RE; 25 } 26 ans[p]=co; 27 for(int i=0;i<v[p].size();i++){ 28 dfs(v[p][i],3-co); 29 } 30 } 31 int main(){ 32 ios::sync_with_stdio(0); 33 cin.tie(0); 34 cin>>n>>s; 35 for(int i=0;i<n;i++){ 36 for(int j=0;j<i;j++){ 37 if(s[j]>s[i]){ 38 v[i].PB(j);v[j].PB(i); 39 } 40 } 41 } 42 for(int i=0;i<n;i++){ 43 if(!ans[i]){ 44 dfs(i,1); 45 } 46 } 47 cout<<"YES "; 48 for(int i=0;i<n;i++)cout<<ans[i]-1; 49 RE 0; 50 }
E2:
注意上一题的规律:如果一个字符它比在它前面的字符小时,那么这两个字符的值必定不同。
那么面对每一个字符,先把它随意归为一类,再看看前面有没有比它大的字符。
用一个dp数组表示上一个这样的字符填了哪种颜色,从前面比它大的字符当中选一个颜色最大的,再在那个字符的基础上再开一个颜色种类。因为所有颜色都是从比它大的颜色延伸过来的,所以这里颜色取的肯定是最小值。同时只有26个字母,不会超时。
代码:
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 V vector 9 #define RE return 10 #define ALL(a) a.begin(),a.end() 11 #define MP make_pair 12 #define PB push_back 13 #define PF push_front 14 #define FILL(a,b) memset(a,b,sizeof(a)) 15 using namespace std; 16 int n,dp[30],ans[200005],maxi;string s; 17 int main(){ 18 ios::sync_with_stdio(0); 19 cin.tie(0); 20 cin>>n>>s; 21 for(int i=0;i<n;i++){ 22 dp[s[i]-‘a‘]=1; 23 for(int j=s[i]-‘a‘+1;j<26;j++)dp[s[i]-‘a‘]=max(dp[s[i]-‘a‘],dp[j]+1); 24 maxi=max(maxi,dp[s[i]-‘a‘]);ans[i]=dp[s[i]-‘a‘]; 25 } 26 cout<<maxi<<‘ ‘; 27 for(int i=0;i<n;i++){ 28 cout<<ans[i]<<‘ ‘; 29 } 30 RE 0; 31 }
F;
这题居然没做出来,后来发现这也太水了吧。。。
但是还是有难度的,首先这里先对每一条边的值都设定成1.
在对每一个限制都尽力满足要求,如果有边比规定的要小,就把它增加到规定的值,先不考虑对不对。
但是可以知道像这样的填法不会有比限制更小的,也是如果有解中最小的解法,其实再大也没有意义。
最后顺着规定检查一遍,如果成立,则输出答案,否则输出-1.
代码:
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 V vector 9 #define RE return 10 #define ALL(a) a.begin(),a.end() 11 #define MP make_pair 12 #define PB push_back 13 #define PF push_front 14 #define FILL(a,b) memset(a,b,sizeof(a)) 15 using namespace std; 16 V<P<int,int> > b[5005]; 17 int f[5005],l[5005],r[5005],d[5005],de[5005],id[5005]; 18 int n,m,fa[5005]; 19 void dfs(int p,int last){ 20 fa[p]=last;de[p]=de[last]+1; 21 for(int i=0;i<b[p].size();i++){ 22 int v=b[p][i].first; 23 if(v==last)continue; 24 dfs(v,p);id[v]=b[p][i].second; 25 } 26 } 27 bool get(int u,int v,int w){ 28 int re=1000000000; 29 if(de[u]<de[v])swap(u,v); 30 while(de[u]>de[v]){ 31 re=min(f[id[u]],re); 32 if(re<w)RE 0; 33 u=fa[u]; 34 } 35 while(u!=v){ 36 re=min(f[id[u]],re); 37 re=min(f[id[v]],re); 38 if(re<w)RE 0; 39 u=fa[u], 40 v=fa[v]; 41 } 42 RE (w==re); 43 } 44 void up(int u,int v,int w){ 45 if(de[u]<de[v])swap(u,v); 46 while(de[u]>de[v]) { 47 f[id[u]]=max(f[id[u]],w);u=fa[u]; 48 } 49 while(u!=v){ 50 f[id[u]]=max(f[id[u]],w), 51 f[id[v]]=max(f[id[v]],w), 52 u=fa[u],v=fa[v]; 53 } 54 } 55 int main(){ 56 ios::sync_with_stdio(0); 57 cin.tie(0); 58 cin>>n;int x,y; 59 FOR(i,1,n-1){ 60 cin>>x>>y; 61 b[x].PB(MP(y,i)), 62 b[y].PB(MP(x,i)); 63 f[i]=1; 64 } 65 dfs(1,0); 66 cin>>m; 67 int u,v,w; 68 FOR(i,1,m){ 69 cin>>u>>v>>w; 70 up(u,v,w); 71 l[i]=u;r[i]=v;d[i]=w; 72 } 73 FOR(i,1,m){ 74 if(!get(l[i],r[i],d[i])){ 75 cout<<-1;RE 0; 76 } 77 } 78 FOR(i,1,n-1)cout<<f[i]<<‘ ‘; 79 return 0; 80 }
值得一提的是这次的最后一题竟然有好多人被hack了,而且都是些MLE和TLE,MLE就是那些记录路径的人,而TLE我猜应该是用了map。
以上是关于CF617(div.3)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #617 (Div. 3) 题解
Codeforces Round #617 (Div. 3)
Codeforces Round #617 (Div. 3)