【noip2016】d1解题报告
t1:玩具谜题,麻烦的模拟
#include<iostream> #include<cstdio> using namespace std; int n,m,tail=1,a,b; struct in { int direct; char name[20 + 5]; }ter[100010]; /*struct zhiling { int a; int b; }ing[100010];*/ //char tt[100010]; int main() { cin>>n>>m; int i,j; for(i=1;i<=n;i++) { scanf("%d", &ter[i].direct); scanf("%s", ter[i].name); // ter[i].name = tt; // cin>>ter[i].direct>>ter[i].name; } for(i=1;i<=m;i++) { cin>>/*ing[i].*/a>>/*ing[i].*/b; b=b%n; if(ter[tail].direct==0&&a==1) { /*for(j=b;j>0;j--) { tail++; if(tail==n+1) { tail=1; } }*/ tail=tail+b; if(tail>n) { tail=tail-n; } } else if(ter[tail].direct==0&&a==0) { /*for(j=b;j>0;j--) { tail--; if(tail==0) { tail=n; } }*/ tail=tail-b; if(tail<=0) { tail=tail+n; } } else if(ter[tail].direct==1&&a==0) { tail=tail+b; if(tail>n) { tail=tail-n; } } else if(ter[tail].direct==1&&a==1) { tail=tail-b; if(tail<=0) { tail=tail+n; } } //cout<<ter[tail].name<<endl; } // cout<<ter[tail].name; printf("%s\n", ter[tail].name); return 0; }
t2:天天爱跑步……真tm难
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<vector> #include<queue> #include<cmath> using namespace std; vector<int>na[600060],ru[600060],to[600060]; int n,m,x,y,z,tail,md,ans[600060],tong[600060],w[600060],val[600060],anto[600060],fa[300030][25],head[300030],de[300030]; struct in { int to,ne; }ter[600060]; inline void build(int f,int l) { ter[++tail]=(in){l,head[f]},head[f]=tail; ter[++tail]=(in){f,head[l]},head[l]=tail; } struct es { int f,l,lca,len; }ing[600060]; void init(int no,int f) { de[no]=de[f]+1; md=max(md,de[no]); fa[no][0]=f; for(int i=head[no];i>0;i=ter[i].ne) { int t=ter[i].to; if(t==f) continue; init(t,no); } } inline void make_lca() { for(int i=1;i<=log2(n);i++) for(int j=1;j<=n;j++) fa[j][i]=fa[fa[j][i-1]][i-1]; } inline int ask(int x,int y) { if(de[x]<de[y]) swap(x,y); for(int i=log2(n);i>=0;i--) if(de[fa[x][i]]>=de[y]) x=fa[x][i]; if(x==y) return x; for(int i=log2(n);i>=0;i--) if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i]; return fa[x][0]; } void dfs(int x,int f) { int no=de[x]+w[x],cun; if(no<=md) cun=tong[no]; for(int i=head[x];i>0;i=ter[i].ne) { int t=ter[i].to; if(t==f) continue; dfs(t,x); } tong[de[x]]+=val[x]; if(no<=md) ans[x]=tong[no]-cun; for(int i=0;i<na[x].size();i++) tong[de[na[x][i]]]--; } void DFS(int x,int f) { int no=de[x]-w[x]+300000;int cun=anto[no]; for(int i=head[x];i>0;i=ter[i].ne) { int t=ter[i].to; if(t==f) continue; DFS(t,x); } for(int i=0;i<ru[x].size();i++) anto[ru[x][i]+300000]++; ans[x]+=anto[no]-cun; for(int i=0;i<to[x].size();i++) anto[to[x][i]+300000]--; } int main() { memset(head,-1,sizeof(head)); scanf("%d%d",&n,&m); for(int i=1;i<n;i++) scanf("%d%d",&x,&y),build(x,y); init(1,0); make_lca(); for(int i=1;i<=n;i++) scanf("%d",&w[i]); for(int i=1;i<=m;i++) scanf("%d%d",&x,&y),val[x]++,ing[i].f=x,ing[i].l=y,ing[i].lca=ask(ing[i].f,ing[i].l),ing[i].len=de[ing[i].f]+de[ing[i].l]-2*de[ing[i].lca]; for(int i=1;i<=m;i++) na[ing[i].lca].push_back(ing[i].f); dfs(1,0); for(int i=1;i<=m;i++) ru[ing[i].l].push_back(de[ing[i].l]-ing[i].len); for(int i=1;i<=m;i++) to[ing[i].lca].push_back(de[ing[i].l]-ing[i].len); DFS(1,0); for(int i=1;i<=m;i++) if(de[ing[i].f]-de[ing[i].lca]==w[ing[i].lca]) ans[ing[i].lca]--; for(int i=1;i<=n;i++) cout<<ans[i]<<' '; }
t3:换教室,原博客http://www.cnblogs.com/Loi-dfkdsmbd/p/7732020.html
#include<iostream> #include<cstring> #include<cstdio> #include<vector> #include<queue> using namespace std; int tail,x[2020],y[2020],a,b,c,head[330],n,m,v,e,ans[2020][2020]; double gai[2020],dp[2020][2020][2],pri; void floyd()//求最短路,预处理 { for(int k=1;k<=v;k++) for(int i=1;i<=v;i++) for(int j=1;j<=v;j++) ans[i][j]=min(ans[i][j],ans[i][k]+ans[j][k]); } int main() { scanf("%d%d%d%d",&n,&m,&v,&e); for(int i=1;i<=n;i++) scanf("%d",&y[i]); for(int i=1;i<=n;i++) scanf("%d",&x[i]); for(int i=1;i<=n;i++) scanf("%lf",&gai[i]); memset(ans,0x3f,sizeof(ans)); for(int i=1;i<=v;i++) ans[i][i]=0; for(int i=1;i<=e;i++) scanf("%d%d%d",&a,&b,&c),ans[a][b]=ans[b][a]=min(c,ans[b][a]); floyd(); memset(dp,127,sizeof(dp)); dp[0][0][0]=dp[1][0][0]=dp[1][1][1]=0;//初始化,一定要记得把dp[1][1][1]赋值为0!!! for(int i=2;i<=n;i++)//一个点都不申请的时候 dp[i][0][0]=ans[y[i-1]][y[i]]+dp[i-1][0][0]; for(int i=2;i<=n;i++) for(int j=1;j<=min(m,i);j++) { dp[i][j][0]=min(dp[i-1][j][0]+ans[y[i-1]][y[i]],dp[i][j][0]);//当这个点不取的时候很简单,就看上一个点是否备取就行 dp[i][j][0]=min(dp[i-1][j][1]+(ans[x[i-1]][y[i]]*gai[i-1]+ans[y[i-1]][y[i]]*(1-gai[i-1])),dp[i][j][0]); dp[i][j][1]=min(dp[i][j][1],dp[i-1][j-1][0]+(ans[y[i-1]][x[i]]*gai[i]+ans[y[i-1]][y[i]]*(1-gai[i])));//当这个点取的时候,要考虑四种情况,a取/不取 b取/不取 dp[i][j][1]=min(dp[i][j][1],dp[i-1][j-1][1]+ ans[x[i-1]][x[i]]*gai[i-1]*gai[i] +ans[x[i-1]][y[i]]*gai[i-1]*(1-gai[i]) +ans[y[i-1]][x[i]]*gai[i]*(1-gai[i-1]) +ans[y[i-1]][y[i]]*(1-gai[i])*(1-gai[i-1])); } pri=dp[n][0][0]; for(int i=1;i<=m;i++)//取个最小值 pri=min(pri,min(dp[n][i][0],dp[n][i][1])); printf("%.2lf",pri); }