NOIP2017普及组题
提高组死亡选手来AK普及(耗时两天)。
T1
#include<bits/stdc++.h> using namespace std; int A,B,C; int main() { cin>>A>>B>>C; cout<<(A*2+B*3+C*5)/10<<"\n"; return 0; }
T2
无脑找答案
#include<bits/stdc++.h> using namespace std; int N,Q,a[1050],b,x,t; int main() { cin>>N>>Q; for(int i=1;i<=N;i++)cin>>a[i]; sort(a+1,a+N+1); while(Q--){ cin>>b>>x; t=pow(10,b); int ans=-1; for(int i=1;i<=N;i++) if(a[i]%t==x){ ans=a[i]; break; } cout<<ans<<"\n"; } return 0; }
T3
连边,取一个有颜色的块,
1.四周有颜色的块 相同连0 不同连1
2.与他距离为2的块 相同连2 不同连3
3.这一点忘了就少一半分,四周没有颜色的块要连2,否则有好多都会误判成“-1”
然后跑SPFA,没了
#include<bits/stdc++.h> using namespace std; int N,M,color[105][105],last[10005],cnt, x,y,z,d1[4]={1,-1,0,0},d2[4]={0,0,-1,1},dis[10005]; int D1[8]={0,0,2,-2,1,1,-1,-1},D2[8]={2,-2,0,0,1,-1,1,-1}; bool vis[10005]; queue <int> q; struct Edge{ int other,pre,val; }e[100005]; void connect(int x,int y,int z){ e[++cnt]=(Edge){y,last[x],z}; last[x]=cnt; } int main() { cin>>M>>N; for(int i=1;i<=N;i++){ cin>>x>>y>>z; color[x][y]=z+1; //0 nah 1 red 2 yellow } for(int i=1;i<=M;i++) for(int j=1;j<=M;j++) if(color[i][j]){ for(int k=0;k<=3;k++){ int tx=i+d1[k],ty=j+d2[k]; if(tx<1||tx>M||ty<1||ty>M)continue; // printf("[%d,%d]\n",tx,ty); if(color[tx][ty]){ int v=1; if(color[tx][ty]==color[i][j])v=0; // printf("(%d,%d)->(%d,%d)cost=%d\n",i,j,tx,ty,v); connect((i-1)*M+j,(tx-1)*M+ty,v); } else { connect((i-1)*M+j,(tx-1)*M+ty,2);// printf("z(%d,%d)->(%d,%d)cost=%d\n",i,j,tx,ty,2); } } for(int l=0;l<=7;l++){ int lx=i+D1[l],ly=j+D2[l]; if(lx<1&&lx>M&&ly<1&&ly>M)continue; if(lx==i&&ly==j)continue; if(!color[lx][ly])continue; int v=3; if(color[i][j]==color[lx][ly])v=2; // printf("(%d,%d)->(%d,%d)cost=%d\n",i,j,lx,ly,v); connect((i-1)*M+j,(lx-1)*M+ly,v); } } memset(dis,0x3f,sizeof dis); vis[1]=1,dis[1]=0; q.push(1); while(!q.empty()){ int u=q.front(); vis[u]=0,q.pop(); for(int i=last[u];i;i=e[i].pre){ int v=e[i].other; if(dis[v]>dis[u]+e[i].val){ dis[v]=dis[u]+e[i].val; if(!vis[v]){ vis[v]=1; q.push(v); } } } } if(dis[M*M]==dis[0])puts("-1"); else printf("%d\n",dis[M*M]); return 0; }
T4
二分答案+DP
朴素DP N^2 我们很容易的看出可以拿单调队列优化
#include<bits/stdc++.h> #define MAXN 500005 #define INF 0x7f7f7f7f using namespace std; int read(){ int x=0,t=1;char c=getchar(); while(c<'0'||c>'9'){if(c=='-')t=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*t; } int N,D,K,x[MAXN],c[MAXN],f[MAXN]; pair <int,int> q[MAXN]; bool Judge(int L){ memset(f,0,sizeof f); int a=D-L,b=D+L,head=0,tail=-1,cur=0; if(a<=0)a=1; for(int i=1;i<=N;i++){ for(cur;cur<i&&x[cur]<=x[i]-a;cur++){ while(head<=tail&&q[tail].first<f[cur])tail--; if(f[cur]<=-INF)continue; q[++tail].first=f[cur],q[tail].second=x[cur]; } while(head<=tail&&x[i]-q[head].second>b)head++; if(head<=tail)f[i]=q[head].first+c[i]; else f[i]=-INF; if(f[i]>=K)return 1; } return 0; } int main() { N=read(),D=read(),K=read(); for(int i=1;i<=N;i++)x[i]=read(),c[i]=read(); if(!Judge(x[N]))puts("-1"); else{ int l=0,r=x[N]; while(l<r){ int mid=l+r>>1; if(Judge(mid))r=mid; else l=mid+1; } printf("%d\n",l); } return 0; }