Codeforces Round #606 Div. 2 比赛总结
比赛情况
bq. A题 Wrong Answer on test 2
, E题sb题没切。bqbqbq.
比赛总结
bq.
那就直接上题解吧!^-^
A
数位dp,分类讨论,注意细节。
Talk is cheap.Show me the code.
#include<bits/stdc++.h> using namespace std; inline int read() { int x=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=(x<<3)+(x<<1)+(ch^48); ch=getchar(); } return x * f; } int n,m,ans,L; void work() { n = read(), ans = 0; L = 0, m = n; while(m/10) ++L, m /= 10; ans += L * 9; L = 1, m = n; while(m/10) L = (L*10)+1, m /= 10; ans += n/L; printf("%d\n",ans); } int main() { int T = read(); while(T--) work(); return 0; }
B
我们把数值一样的数放在一起,扔进堆里。按数值从大到小处理就OK了。
注意值域比较大,用一下 里面的 map
。
Talk is cheap.Show me the code.
#include<bits/stdc++.h> using namespace std; inline int read() { int x=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=(x<<3)+(x<<1)+(ch^48); ch=getchar(); } return x * f; } const int N = 2e5+7; int n; int a[N]; void work() { map<int,int> s; priority_queue<int> q; n = read(); int ans = 0; for(int i=1;i<=n;++i) { a[i] = read(); if(s[a[i]]==0) { q.push(a[i]); } ++s[a[i]]; } while(!q.empty()) { int now = q.top(); q.pop(); if(now&1) continue; if(s[now/2]==0) q.push(now/2); s[now/2] += s[now]; ans++; //printf("ans += s[%d], s[now]=%d\n",now,s[now]); } printf("%d\n",ans); } int main() { //freopen("a.out","w",stdout); int T = read(); while(T--) work(); return 0; }
C
贪心题。
如果有 twone
则删去 'o',否则删去中间这个,比如 one
删去 'n'。这样是对的。
然后模拟即可。
Talk is cheap.Show me the code.
#include<bits/stdc++.h> using namespace std; inline int read() { int x=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=(x<<3)+(x<<1)+(ch^48); ch=getchar(); } return x * f; } void work() { string s; cin>>s; vector<int> Ans; for(int i=1;i<s.length();++i) { char a = s[i-1], b = s[i], c = s[i+1]; if(a=='t' && b=='w' && c=='o') { if(s[i+2]=='n' && s[i+3]=='e') s[i+1] = '-', Ans.push_back(i+1)/*, i = i+3+1*/; else s[i] = '-', Ans.push_back(i)/*, i = i+1+1*/; } else if(a=='o' && b=='n' && c=='e') { Ans.push_back(i); } } printf("%d\n",(int)Ans.size()); for(int i=0;i<Ans.size();++i) printf("%d ",Ans[i]+1); puts(""); } int main() { //freopen("a.out","w",stdout); int T = read(); while(T--) work(); return 0; }
D
待补坑。
E
炒鸡简单
考虑一张下面这样的图:
答案不就是两个蓝色部分的大小相乘吗?(题目不考虑A,B两点)
这不就是Dfs的事吗qwq
(其实如果这两块蓝色的有边将他们连起来了就是 puts("0"))
Talk is cheap.Show me the code.
#include<bits/stdc++.h> using namespace std; inline int read() { int x=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=(x<<3)+(x<<1)+(ch^48); ch=getchar(); } return x * f; } const int N = 2e5+7, M = 5e5+7; int n,m,a,b,cnt,flag,tot; int head[N],vis[N]; struct Edge { int next,to; }edge[M<<1]; inline void add(int u,int v) { edge[++cnt] = (Edge)<%head[u],v%>; head[u] = cnt; } void Dfs(int u,int F) { flag |= (u==F); vis[u] = 1; ++tot; for(int i=head[u];i;i=edge[i].next) { int v = edge[i].to; if(!vis[v]) Dfs(v,F); } } void work() { memset(head, 0, sizeof(head)); cnt = flag = 0; n = read(), m = read(), a = read(), b = read(); for(int i=1,u,v;i<=m;++i) { u = read(), v = read(); add(u,v), add(v,u); } memset(vis, 0, sizeof(vis)); vis[a] = 1; int n1 = 0, n2 = 0, nxt = 0; for(int i=head[a];i;i=edge[i].next) { int v = edge[i].to; tot = 0; Dfs(v,b); if(flag) { n1 = n - tot - 1; break; } } memset(vis, 0, sizeof(vis)); vis[b] = 1; flag = 0; for(int i=head[b];i;i=edge[i].next) { int v = edge[i].to; tot = 0; Dfs(v,a); if(flag) { n2 = n - tot - 1; break; } } printf("%lld\n",(long long)(1ll*n1*n2)); } int main() { int T = read(); while(T--) work(); return 0; }
F
待补坑。