2020南京部分题解
E题
队友写的构造
#include<bits/stdc++.h> #define LL long long using namespace std; const int maxn=1e5+5; string s; int mx,my; int cnt[4]; void _move(int &x,int &y,int k) { if(k==0) y++; else if(k==1) y--; else if(k==2) x--; else if(k==3) x++; } void print(int k) { if(k==0) printf("U"); else if(k==1) printf("D"); else if(k==2) printf("L"); else if(k==3) printf("R"); } bool check(int a,int b,int c,int d) { int x=0,y=0; for(int i=1; i<=cnt[a]; i++) { _move(x,y,a); if(x==mx&&y==my) return false; } for(int i=1; i<=cnt[b]; i++) { _move(x,y,b); if(x==mx&&y==my) return false; } for(int i=1; i<=cnt[c]; i++) { _move(x,y,c); if(x==mx&&y==my) return false; } for(int i=1; i<=cnt[d]; i++) { _move(x,y,d); if(x==mx&&y==my) return false; } for(int i=1; i<=cnt[a]; i++) print(a); for(int i=1; i<=cnt[b]; i++) print(b); for(int i=1; i<=cnt[c]; i++) print(c); for(int i=1; i<=cnt[d]; i++) print(d); printf("\n"); return true; } int main() { int T; scanf("%d",&T); while(T--) { memset(cnt,0,sizeof(cnt)); cin>>mx>>my>>s; if(mx==0&&my==0) { printf("Impossible\n"); continue; } int ex=0,ey=0; for(int i=0; i<s.length(); i++) { if(s[i]=='U') { cnt[0]++; ey++; } else if(s[i]=='D') { cnt[1]++; ey--; } else if(s[i]=='L') { cnt[2]++; ex--; } else if(s[i]=='R') { cnt[3]++; ex++; } } if(mx==ex&&my==ey) { printf("Impossible\n"); continue; } bool flag=false; for(int i=0; i<4; i++) { if(flag==true) continue; for(int j=0; j<4; j++) { if(i==j||flag==true) continue; for(int k=0; k<4; k++) { if(k==i||k==j||flag==true) continue; for(int m=0; m<4; m++) { if(m==i||m==j||m==k||flag==true) continue; flag=check(i,j,k,m); } } } } if(flag==false) printf("Impossible\n"); } return 0; }
K题
队友写的签到
#include<bits/stdc++.h> using namespace std; const int N=1e6+10; int main(){ int n,k; cin>>n>>k; int i=1; if(k==0){ cout<<"-1"<<endl; return 0; } if(n==1){ cout<<"1"<<endl; return 0; } if(k==1){ for(i;i<n;i++)printf("%d ",i); printf("%d\n",n); } else if(k==n){ if(n%2==0){ for(i;i<=n;i+=2){ if(i==n-1){ printf("%d %d\n",i+1,i); } else printf("%d %d ",i+1,i); } } else{ cout<<1<<endl; for(i=2;i<=n;i+=2){ if(i==n-1){ printf("%d %d\n",i+1,i); } else printf("%d %d ",i+1,i); } } } else{ if(k%2==0){ for(i;i<=k;i+=2){ if(i==n-1){ printf("%d %d\n",i+1,i); } else printf("%d %d ",i+1,i); } for(i=k+1;i<n;i++){ printf("%d ",i); } printf("%d\n",n); }else{ printf("%d ",1); for(i=2;i<=k;i+=2){ if(i==n-1){ printf("%d %d\n",i+1,i); } else printf("%d %d ",i+1,i); } for(i=k+1;i<n;i++){ printf("%d ",i); } printf("%d\n",n); } } }
L题
容易想到的是,根据位置大小,就是求取将所有ab按距离排序后,最长的连续a是多少
注意当距离相等时,a不能算
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e6+10; const int mod=1e9+7; const int inf=0x3f3f3f3f; int a[N]; int b[N]; int sign[N]; int main(){ ios::sync_with_stdio(false); int t; cin>>t; while(t--){ int n,m; cin>>n>>m; int i,j; for(i=1;i<=n;i++){ cin>>a[i]; } for(i=1;i<=m;i++){ cin>>b[i]; } sort(a+1,a+1+n); sort(b+1,b+1+m); int cnt=0; for(i=1,j=1;i<=n&&j<=m;){ if(a[i]>b[j]){ sign[++cnt]=1; j++; } else if(a[i]<b[j]){ sign[++cnt]=2; i++; } else{ sign[++cnt]=1; while(a[i]==b[j]){ i++; } j++; } } while(i<=n){ sign[++cnt]=2; i++; } while(j<=m){ sign[++cnt]=1; j++; } int ans=0; int tmp=0; for(i=1;i<=cnt;i++){ if(sign[i]==1){ tmp=0; continue; } tmp++; ans=max(ans,tmp); } if(!ans){ cout<<"Impossible"<<endl; } else{ cout<<ans<<endl; } } }
M题
题目给的信息基本上可以推出状态
初始的树形dp可以写成f[i][j][k]表示以i为根,删了j个,当前i有没有删
第三维是因为我们要根据i的状态确定最后的答案
我写的更新t掉了,因为复杂度不正确,正确的复杂度是枚举到子树大小,因为这样可以保证两两点只相互更新一次
#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 h[N],ne[N],e[N],idx; ll a[N],p[N]; ll f[2020][2020][2]; int depth[N]; int sz[N]; ll sum[N]; struct node{ int a; ll b; int c; }; void add(int a,int b){ e[idx]=b,ne[idx]=h[a],h[a]=idx++; } void dfs(int u,int fa){ int i; sz[u]=1; f[u][0][0]=a[u]; f[u][1][1]=0; ll res=0; int j,k; ll tmp[2020][2]; for(i=h[u];i!=-1;i=ne[i]){ int j=e[i]; if(j==fa) continue; dfs(j,u); for(int x=0;x<=sz[u]+sz[j];x++){ tmp[x][0]=tmp[x][1]=1e18; } for(int x=0;x<=sz[u];x++){ for(int y=0;y<=sz[j];y++){ tmp[x+y][0]=min(tmp[x+y][0],f[u][x][0]+f[j][y][0]+a[j]); tmp[x+y][0]=min(tmp[x+y][0],f[u][x][0]+f[j][y][1]); tmp[x+y][1]=min(tmp[x+y][1],f[u][x][1]+f[j][y][0]); tmp[x+y][1]=min(tmp[x+y][1],f[u][x][1]+f[j][y][1]); } } sz[u]+=sz[j]; for(int i=0;i<=sz[u];i++) f[u][i][0]=tmp[i][0],f[u][i][1]=tmp[i][1]; } } int main(){ ios::sync_with_stdio(false); int t; cin>>t; while(t--){ int n; cin>>n; idx=0; int i; for(i=0;i<=n;i++){ h[i]=-1; } for(i=2;i<=n;i++){ cin>>p[i]; add(i,p[i]); add(p[i],i); } for(i=1;i<=n;i++){ cin>>a[i]; sum[i]=a[i]; } for(i=1;i<=n;i++){ for(int j=0;j<=n;j++){ f[i][j][0]=f[i][j][1]=1e18; } } for(i=1;i<=n;i++){ sum[p[i]]+=a[i]; } depth[1]=1; dfs(1,-1); ll ans=0; for(i=1;i<=n;i++){ ans+=sum[i]; } for(i=0;i<=n;i++){ cout<<min(f[1][i][0],f[1][i][1])<<" "; } cout<<endl; } }
没有人不辛苦,只有人不喊疼