noip2014 提高组
T1 生活大爆炸版 石头剪刀布 题目传送门
就是道模拟题咯
#include<algorithm> #include<cstdio> #include<cstring> using namespace std; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int a,b,n; int x[251],y[251],g[251],f[251]; int w[6][6]={{2,0,1,1,0},{1,2,0,1,0},{0,1,2,0,1},{0,0,1,2,1},{1,1,0,0,2}}; int main() { n=read(); int la=read(),lb=read(); for(int i=0;i<la;i++) x[i]=read(); for(int i=0;i<lb;i++) y[i]=read(); for(int i=0;i<n;i++) g[i]=x[i%la],f[i]=y[i%lb]; for(int i=0;i<n;i++){ if(w[g[i]][f[i]]==0) b++; if(w[g[i]][f[i]]==1) a++; } printf("%d %d ",a,b); return 0; }
T2 联合权值 题目传送门
易证明和某一个点相连接的点 他们之间的距离就是2 所以我们可以枚举每一个点求值 当然一个一个点去求值太慢
这个时候我们发现了一个神奇的东西 他叫做——加法结合律! 问题就完美解决了.
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int M=450007,mod=10007; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,first[M],cnt,ans,mx,w[M]; struct node{int to,next;}e[M]; void ins(int a,int b){cnt++; e[cnt].to=b; e[cnt].next=first[a]; first[a]=cnt;} void insert(int a,int b){ins(a,b); ins(b,a);} void dfs(int x){ int mx1=0,mx2=0,sum=0; for(int i=first[x];i;i=e[i].next){ int now=e[i].to; sum=(sum+w[now])%mod; if(w[now]>mx1) mx2=mx1,mx1=w[now]; else if(w[now]>mx2) mx2=w[now]; } mx=max(mx,mx1*mx2); for(int i=first[x];i;i=e[i].next){ int now=e[i].to; ans=(ans+w[now]*((sum-w[now])%mod+mod)%mod)%mod; } } int main() { int x,y; n=read(); for(int i=1;i<n;i++) x=read(),y=read(),insert(x,y); for(int i=1;i<=n;i++) w[i]=read(); for(int i=1;i<=n;i++) dfs(i); printf("%d %d ",mx,ans); return 0; }