noip2014
生活大爆炸版石头剪刀布
模拟==
void rule(int x,int y){ if(x==0&&y==1) ++bb; if(x==0&&y==2) ++aa; if(x==0&&y==3) ++aa; if(x==0&&y==4) ++bb; if(x==1&&y==0) ++aa; if(x==1&&y==2) ++bb; if(x==1&&y==3) ++aa; if(x==1&&y==4) ++bb; if(x==2&&y==0) ++bb; if(x==2&&y==1) ++aa; if(x==2&&y==3) ++bb; if(x==2&&y==4) ++aa; if(x==3&&y==0) ++bb; if(x==3&&y==1) ++bb; if(x==3&&y==2) ++aa; if(x==3&&y==4) ++aa; if(x==4&&y==0) ++aa; if(x==4&&y==1) ++aa; if(x==4&&y==2) ++bb; if(x==4&&y==3) ++bb; } int main(){ rd(n),rd(na),rd(nb); for( int i=1;i<=na;++i) rd(a[i]); for(r int i=1;i<=nb;++i) rd(b[i]); int x=0,y=0;//从0开始!!!!! for(int i=1;i<=n;++i){ if(++x>na) x=1;if(++y>nb) y=1; rule(a[x],b[y]); } printf("%d %d",aa,bb); return 0; }
康了yyb的,大佬做水题的姿势都比我高端!!!
int ans[5][5]={0,-1,1,1,-1,1,0,-1,1,-1,-1,1,0,-1,1,-1,-1,1,0,1,1,1,-1,-1,0}; int n,na,nb,a[500],b[500],A,B; int main(){ rd(n),rd(na),rd(nb); for( int i=1;i<=na;++i) rd(a[i]); for(r int i=1;i<=nb;++i) rd(b[i]); for(int i=1,d;i<=n;++i){ d=ans[a[i%na]][b[i%nb]]; if(d==1)A+=1;if(d==-1)B+=1; } printf("%d %d\n",A,B); return 0; }
联合权值
因为求的是距离为2的点对 只用枚举和一个点连接的儿子 儿子权值和的平方再减去各个权值的平方 最大值就用最大和次大值相乘
int tot=0,head[N]; struct edge{int v,nxt;}e[N<<1]; void add(int u,int v){e[++tot]=(edge){v,head[u]},head[u]=tot;} int main(){ #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif rd(n); for(int i=1,u,v;i<n;++i) rd(u),rd(v),add(u,v),add(v,u); for(int i=1;i<=n;++i) rd(a[i]); for(int u=1,mx,cm;u<=n;++u){ mx=0,cm=0; for(int i=head[u],v;i;i=e[i].nxt){ sum[u]=(sum[u]+a[v=e[i].v])%P,sum2[u]=(sum2[u]+a[v]*a[v])%P; if(a[v]>mx) cm=mx,mx=a[v]; else if(a[v]>cm) cm=a[v]; } ans=max(ans,mx*cm); } printf("%d ",ans),ans=0; for(int i=1;i<=n;++i) ans=(ans+sum[i]*sum[i]-sum2[i])%P; printf("%d",ans); return 0; }
飞扬的小鸟
\(f[i][j]\)表示跳到坐标\((i,j)\)所需要的最小步数 注意处理跳上天花板去的情况
跳的时候相当于背包?
struct node{int l,h;}a[N]; int main(){ #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif rd(n),rd(m),rd(k); for(int i=0;i<n;++i) rd(X[i]),rd(Y[i]),a[i]=(node){0,m+1};a[n]=(node){0,m+1}; memset(f,inf,sizeof(f)),memset(vis,0,sizeof(vis)); for(int i=1;i<=m;++i) f[0][i]=0; for(int i=1,p,l,h;i<=k;++i) rd(p),rd(l),rd(h),a[p]=(node){l,h},vis[p]=1; for(int i=1;i<=n;++i){ for(int j=X[i-1]+1;j<=m+X[i-1];++j) f[i][j]=min(f[i-1][j-X[i-1]]+1,f[i][j-X[i-1]]+1); for(int j=m;j<=m+X[i-1];++j) f[i][m]=min(f[i][j],f[i][m]);//天花板 for(int j=1;j<=m-Y[i-1];++j) f[i][j]=min(f[i][j],f[i-1][j+Y[i-1]]);//不跳 for(int j=1;j<=a[i].l;++j) f[i][j]=inf; for(int j=a[i].h;j<=m;++j) f[i][j]=inf; } for(int i=1;i<=m;++i) ans=min(ans,f[n][i]); if(ans<inf) return printf("1\n%d",ans),0; int i,j,cnt;ans=0; for(i=n;i>=0;--i){ for(j=1;j<=m;++j) if(f[i][j]<inf) break; if(j<=m) break; } for(j=0;j<=i;++j) ans+=vis[j]; printf("0\n%d",ans); return 0; }
无线网络发射站选址
有很多种方法 直接暴力搞也行 二位前缀和也行
int main(){ rd(d),rd(n); int x,y,w,sum=0,mx=0,ans=1; for(int i=1;i<=n;++i) rd(x),rd(y),rd(w),mp[x+20][y+20]=w; for(int i=20;i<=148;++i) for(int j=20;j<=148;++j){ for(int wi=i-d;wi<=i+d;++wi) for(int wj=j-d;wj<=j+d;++wj) sum+=mp[wi][wj];//以(i,j)为中心的矩阵的和 if(mx==sum) ++ans; else if(mx<sum) ans=1,mx=sum; sum=0; } printf("%d %d",ans,mx); return 0; }
int main(){ int d,n,x,y,w; memset(a,0,sizeof(a)); rd(d),rd(n); for(int i=1;i<=n;++i) rd(x),rd(y),rd(a[x+20][y+20]); for(int i=20-d;i<=148+d;++i) for(int j=20-d;j<=148+d;++j) a[i][j]+=a[i][j-1]+a[i-1][j]-a[i-1][j-1]; int sum,ans=1,mx=0; for(int i=20;i<=148;++i) for(int j=20;j<=148;++j){ sum=a[i+d][j+d]-a[i+d][j-d-1]-a[i-d-1][j+d]+a[i-d-1][j-d-1]; if(sum==mx) ++ans; if(sum>mx) mx=sum,ans=1; } printf("%d %d",ans,mx); return 0; }
寻找道路
重做并没有用心....
先dfs一遍将合法的点搞出来
然后再跑最短路
priority_queue<pii>q; int dis[N];bool vis[N],ok[N],no[N]; void dfs(int u){ for(int i=head[u],v;i;i=e[i].nxt) if(!ok[v=e[i].v]) ok[v]=1,dfs(v); } void dij(){ memset(dis,inf,sizeof(dis)),memset(vis,0,sizeof(vis)); q.push(make_pair(dis[T]=0,T)); while(!q.empty()){ int u=q.top().second;q.pop(); if(vis[u]||no[u]) continue;vis[u]=1; for(int i=head[u],v;i;i=e[i].nxt) if(!no[v=e[i].v]&&dis[v]>dis[u]+1) dis[v]=dis[u]+1,(!vis[v])?(q.push(make_pair(-dis[v],v)),1):1; } } int main(){ #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif rd(n),rd(m); for(int i=1,u,v;i<=m;++i) rd(u),rd(v),(u==v)?(1):(add(v,u),1); rd(S),rd(T); dfs(T);ok[T]=1; for(int u=1;u<=n;++u) if(!ok[u]) for(int i=head[u];i;i=e[i].nxt) no[e[i].v]=1; dij(); if(dis[S]>=inf) return puts("-1"),0; printf("%d",dis[S]); return 0; }
解方程
\(\begin{align*}f(x)&=a_nx^n+a_{n-1}x^{n-1}+...+a_1x_1+a_0x^0\\&=(a_nx^{n-1}+a_{n-1}x^{n-2} +...+a_2x+a_1)x+a_0\\&=(...((a_nx+a_{n-1})x+a_{n-2})x+...+a_1)x+a_0 \end{align*}\)
虽然并没有懂次数也可以模掉这操作
最好还是多选几个质数模一下
int main(){ #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif rd(n),rd(m); for(int i=0;i<=n;++i) rd(a[i]); for(ll x=1;x<=m;++x){ ll ret=1ll,sum=a[0]; for(int i=1;i<=n;++i) ret=ret*x%P,sum=(sum+ret*(ll)a[i]%P)%P; if(!sum) ans[++ans[0]]=x; } printf("%d\n",ans[0]); for(int i=1;i<=ans[0];++i) printf("%d\n",ans[i]); return 0; }