codeforces Round #541 (Div 2)
Posted paul-guderian
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforces Round #541 (Div 2)相关的知识,希望对你有一定的参考价值。
A Sea Battle
平移过后即外围的$(w_{2} + 2) imes (h_{1} + h_{2} + 2)$的矩形周长;
1 #include<bits/stdc++.h> 2 using namespace std; 3 int main(){ 4 int w1,w2,h1,h2; 5 cin>>w1>>h1>>w2>>h2; 6 int a=w1+2,b=h1+h2+2; 7 cout<<((a+b)<<1)-4<<endl; 8 return 0; 9 }
B Draw!
为了方便设初始比分为$(-1,-1)$,假设上一次的比分为$(x_{0},y_{0})$,这次比分为$(x_{1},y_{1})$
若:1.$max(x_{0} , y_{0}) > min(x_{1} , y_{1}) $ 此时变化中一定不会出现相同的情况;
2.$max(x_{0} , y_{0}) <= min(x_{1} , y_{1})$最优的情况是将$x_{0},y_{0}$都先变成较大值,再一起增加,最后再单个增加;
注意对$x==y$的一点点特判;
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,a,b,la,lb; 4 int main(){ 5 scanf("%d",&n); 6 la=lb=-1; 7 long long ans=0; 8 for(int i=1;i<=n;++i){ 9 scanf("%d%d",&a,&b); 10 ans+=max(min(a,b)-max(la,lb)+(la!=lb),0); 11 la=a,lb=b; 12 } 13 cout<<ans<<endl; 14 return 0; 15 }
C Birthday
做法好像还挺多,我不会证明,所以虽然过了也不知对不对,如果评论区有大佬路过的话欢迎评论;
比较麻烦的是两端怎么处理;
排序之后左半边奇数位顺序排列,然后再接偶数位的逆序排列;
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=110; 4 int n,a[N]; 5 int main(){ 6 scanf("%d",&n); 7 for(int i=1;i<=n;++i)scanf("%d",&a[i]); 8 sort(a+1,a+n+1); 9 for(int i=1;i<=n;i+=2)printf("%d ",a[i]); 10 if(n&1)n--;for(int i=n;i;i-=2)printf("%d ",a[i]); 11 return 0; 12 }
D Gourmet choice
相当于只有‘>‘,‘=‘,对等于符号用并查集缩点;
对x>y建边:x->y;
对于得到DAG,记录一个点出发的最长链,即为答案;
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=2010; 4 int n,m,f[N],mx[N],o=1,hd[N],vis[N]; 5 char s[N][N]; 6 struct Edge{int v,nt;}E[N*N]; 7 void adde(int u,int v){E[o]=(Edge){v,hd[u]};hd[u]=o++;} 8 bool dfs(int u){ 9 mx[u]=vis[u]=1; 10 for(int i=hd[u];i;i=E[i].nt){ 11 int v=E[i].v; 12 if(vis[v]==1)return false; 13 if(!vis[v]){if(!dfs(v))return false;} 14 mx[u]=max(mx[u],mx[v]+1); 15 } 16 vis[u]=2; 17 return true; 18 } 19 int find(int x){return f[x]==x?x:f[x]=find(f[x]);} 20 int main(){ 21 #ifndef ONLINE_JUDGE 22 freopen("D.in","r",stdin); 23 freopen("D.out","w",stdout); 24 #endif 25 scanf("%d%d",&n,&m); 26 for(int i=1;i<=n+m;++i)f[i]=i; 27 for(int i=1;i<=n;++i)scanf("%s",s[i]+1); 28 for(int i=1;i<=n;++i) 29 for(int j=1;j<=m;++j)if(s[i][j]==‘=‘)f[find(i)]=find(j+n); 30 for(int i=1;i<=n;++i) 31 for(int j=1;j<=m;++j) 32 if(s[i][j]==‘>‘)adde(find(i),find(j+n)); 33 else if(s[i][j]==‘<‘)adde(find(j+n),find(i)); 34 for(int i=1;i<=n+m;++i)if(find(i)==i&&!vis[i]){ 35 if(!dfs(i)){puts("NO");return 0;} 36 } 37 puts("YES"); 38 for(int i=1;i<=n;++i)printf("%d ",mx[find(i)]); 39 printf(" "); 40 for(int i=1;i<=m;++i)printf("%d ",mx[find(i+n)]); 41 printf(" "); 42 return 0; 43 }
E String Multiplication
考虑每一个字符,分情况模拟即可:
对于$a+b$,
如果$b$是一个全为$x$的串,仅会连接原来的字符$x$,其余置1;
如果$b$是一个首末连续段不相接但是都为$x$的段,修改$x$,其余置1;
如果$b$是一个首末连续段不相接为$x,y(x!=y)$的段,修改$x,y$,其余置1;
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=100010; 4 int n,len,a[26],b[26],lt,p1,p2; 5 char s[N]; 6 inline void upd(int&x,int y){if(x<y)x=y;} 7 void cal(){ 8 len=strlen(s+1); 9 p1=1;while(p1<len&&s[1]==s[p1+1])p1++; 10 p2=1;while(p2<len&&s[len]==s[len-p2])p2++; 11 for(int i=1,cnt=1;i<len;++i)if(s[i]!=s[i+1]){ 12 upd(a[s[i]-‘a‘], cnt); 13 cnt=1; 14 }else cnt++; 15 upd(a[s[len]-‘a‘], p2); 16 } 17 int main(){ 18 #ifndef ONLINE_JUDGE 19 freopen("E.in","r",stdin); 20 freopen("E.out","w",stdout); 21 #endif 22 scanf("%d",&n); 23 scanf("%s",s+1);cal(); 24 for(int i=0;i<26;++i)b[i]=a[i],a[i]=0; 25 for(int i=1;i<n;++i){ 26 scanf("%s",s+1);cal(); 27 if(p1==len){ 28 int x=s[1]-‘a‘; 29 b[x]=a[x]*b[x]+a[x]+b[x]; 30 for(int j=0;j<26;++j)if(j!=x)b[j]=b[j]?1:0; 31 }else if(s[1]==s[len]){ 32 int x=s[1]-‘a‘; 33 if(b[x])b[x]=p1+p2+1; 34 for(int j=0;j<26;++j)if(j!=x)b[j]=b[j]?1:0; 35 }else{ 36 int x=s[1]-‘a‘,y=s[len]-‘a‘; 37 if(b[x])b[x]=p1+1; 38 if(b[y])b[y]=p2+1; 39 for(int j=0;j<26;++j)if(j!=x&&j!=y)b[j]=b[j]?1:0; 40 } 41 for(int j=0;j<26;++j)upd(b[j],a[j]),a[j]=0; 42 } 43 int ans=0; 44 for(int i=0;i<26;++i)upd(ans, b[i]); 45 cout<<ans<<endl; 46 return 0; 47 }
F Asya And Kittens
用并查集模拟,同时维护两边的位置即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=150100; 4 int n,d[N],pre[N],nxt[N],f[N]; 5 vector<int>g[N]; 6 void adde(int u,int v){ 7 g[u].push_back(v); 8 g[v].push_back(u); 9 d[u]++; 10 d[v]++; 11 } 12 void dfs(int u,int fa){ 13 printf("%d ",u); 14 for(int i=0;i<(int)g[u].size();++i){ 15 if(g[u][i]!=fa)dfs(g[u][i],u); 16 } 17 } 18 int find(int x){return f[x]==x?x:f[x]=find(f[x]);} 19 int main(){ 20 scanf("%d",&n); 21 for(int i=1;i<=n;++i)pre[i]=nxt[i]=f[i]=i; 22 for(int i=1;i<n;++i){ 23 int x,y; 24 scanf("%d%d",&x,&y); 25 x=find(x),y=find(y); 26 adde(nxt[x],pre[y]); 27 nxt[x]=nxt[y]; 28 f[y]=x; 29 } 30 int rt=0; 31 for(int i=1;i<=n;++i)if(d[i]==1){rt=i;break;} 32 dfs(rt,0); 33 return 0; 34 }
G
还没有改完。。。
以上是关于codeforces Round #541 (Div 2)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #541 (Div. 2) (A~F)
Codeforces Round #541 (Div. 2) D 并查集 + 拓扑排序