Codeforces Round #551题解
A题
枚举记录
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=2e6+10; const int mod=1e9+7; const int inf=0x3f3f3f3f; int s[N],d[N]; int cnt[N]; int main(){ ios::sync_with_stdio(false); int n,t; cin>>n>>t; int i; for(i=1;i<=n;i++){ cin>>s[i]>>d[i]; for(int j=s[i];j<=200000;j+=d[i]){ cnt[j]=i; } } for(i=t;;i++){ if(cnt[i]){ cout<<cnt[i]<<endl; return 0; } } }
B题
由于每个位置都受行列影响
因此当为1的时候,就取行列最小值,这样一定能够做出答案
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=2e6+10; const int mod=1e9+7; const int inf=0x3f3f3f3f; int s[220][220]; int a[220]; int b[220]; int sign[220]; int main(){ ios::sync_with_stdio(false); int n,m,h; cin>>n>>m>>h; int i,j; for(i=1;i<=m;i++){ cin>>b[i]; } for(i=1;i<=n;i++){ cin>>a[i]; } for(i=1;i<=n;i++){ for(j=1;j<=m;j++){ cin>>s[i][j]; } } for(i=1;i<=n;i++){ for(j=1;j<=m;j++){ if(s[i][j]){ s[i][j]=max(s[i][j],min(a[i],b[j])); } } } for(i=1;i<=n;i++){ for(j=1;j<=m;j++){ cout<<s[i][j]<<" "; } cout<<endl; } }
C题
构造题,因为要求的是前面都不一样但是最后一样
因此我们用贪心的思想,前面都填(,直到我们可以满足条件,就都填右括号
之后判一下非法条件
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=2e6+10; const int mod=1e9+7; const int inf=0x3f3f3f3f; int cnt[N]; int sufa[N]; int sufb[N]; int main(){ ios::sync_with_stdio(false); int n; string s; cin>>n>>s; s=" "+s; int i; if(s[n]=='?'){ s[n]=')'; } if(s[1]=='?') s[1]='('; if(s[1]!='('||s[n]!=')'){ cout<<":("<<endl; return 0; } for(i=n;i>=1;i--){ cnt[i]=cnt[i+1]; sufa[i]=sufa[i+1]; sufb[i]=sufb[i+1]; if(s[i]==')') sufa[i]++; else if(s[i]=='?') cnt[i]++; else{ sufb[i]++; } } int res=0; int flag=0; for(i=1;i<=n;i++){ if(s[i]=='('){ res++; sufb[i]--; } else if(s[i]=='?'){ res++; s[i]='('; cnt[i]--; } else{ res--; sufa[i]--; } if(res+sufb[i]==cnt[i]+sufa[i]){ flag=1; for(int j=i;j<=n;j++){ if(s[j]=='?') s[j]=')'; } break; } if(res==0){ break; } } if(flag){ res=0; for(i=1;i<n;i++){ if(s[i]=='(') res++; else res--; if(res==0){ flag=0; break; } } } if(!flag){ cout<<":("<<endl; } else{ cout<<s.substr(1)<<endl; } }
D题
dp+贪心,设计状态为当前点最高能取到第几大的
如果是1,那么就子树取min
否则就把子树全部相加
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=2e6+10; const int mod=998244353; const int inf=0x3f3f3f3f; int a[N]; int sz[N],f[N]; int h[N],ne[N],e[N],idx; int n; void add(int a,int b){ e[idx]=b,ne[idx]=h[a],h[a]=idx++; } void dfs(int u,int fa){ int i; if(h[u]==-1){ f[u]=1; sz[u]=1; return ; } if(a[u]) f[u]=n; for(i=h[u];i!=-1;i=ne[i]){ int j=e[i]; if(j==fa) continue; dfs(j,u); sz[u]+=sz[j]; if(a[u]){ f[u]=min(f[u],f[j]); } else{ f[u]+=f[j]; } } } int main(){ ios::sync_with_stdio(false); memset(h,-1,sizeof h); int i; cin>>n; for(i=1;i<=n;i++){ cin>>a[i]; } for(i=2;i<=n;i++){ int x; cin>>x; add(x,i); } dfs(1,-1); cout<<sz[1]-f[1]+1<<endl; }
没有人不辛苦,只有人不喊疼