终于有时间来总结一下noip2014了。。。。。。
蒟蒻360 SD 并列rank 76(无限仰慕fye神,TA神,Rivendell神。。。)
总结一下:
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Day1 T1,Day2 T2 水题两道,要做到又好又快。。。 code:
#include<cstdio> #include<cstring> #include<iostream> using namespace std; int a[201],b[201],n,na,nb; int main() { int i,sca,scb; freopen("rps.in","r",stdin); freopen("rps.out","w",stdout); memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); scanf("%d%d%d",&n,&na,&nb); for (i=1;i<=na;++i) scanf("%d",&a[i]); for (i=na+1;i<=n;++i) a[i]=a[(i-1)%na+1]; for (i=1;i<=nb;++i) scanf("%d",&b[i]); for (i=nb+1;i<=n;++i) b[i]=b[(i-1)%nb+1]; sca=0; scb=0; for (i=1;i<=n;++i) { if (a[i]==0) { if ((b[i]==2)||(b[i]==3)) sca++; if ((b[i]==1)||(b[i]==4)) scb++; } if (a[i]==1) { if ((b[i]==0)||(b[i]==3)) sca++; if ((b[i]==2)||(b[i]==4)) scb++; } if (a[i]==2) { if ((b[i]==1)||(b[i]==4)) sca++; if ((b[i]==0)||(b[i]==3)) scb++; } if (a[i]==3) { if ((b[i]==2)||(b[i]==4)) sca++; if ((b[i]==0)||(b[i]==1)) scb++; } if (a[i]==4) { if ((b[i]==0)||(b[i]==1)) sca++; if ((b[i]==2)||(b[i]==3)) scb++; } } printf("%d %d\n",sca,scb); fclose(stdin); fclose(stdout); return 0; }
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int map[200][200]; int maxn,maxi,d,n; int main() { int i,j,x,y,k,m,ans; freopen("wireless.in","r",stdin); freopen("wireless.out","w",stdout); scanf("%d",&d); memset(map,0,sizeof(map)); scanf("%d",&n); for (i=1;i<=n;++i) { scanf("%d%d%d",&x,&y,&k); map[x][y]=k; } maxn=0; maxi=0; for (i=0;i<=128;++i) for (j=0;j<=128;++j) { ans=0; for (k=max(0,i-d);k<=min(128,i+d);++k) for (m=max(0,j-d);m<=min(128,j+d);++m) ans+=map[k][m]; if (ans==maxn) maxi++; if (ans>maxn) {maxn=ans; maxi=1;} } printf("%d %d\n",maxi,maxn); fclose(stdin); fclose(stdout); return 0; }---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
link树形DP,但需要一些小技巧,DFS建树,穷举中间节点,处理同层和上下两层(考试想简单了,60)AC CODE:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int next[500000],point[250000]; int a[250000]={0},n,ans,maxn; int e[500000]; void treedp(int now,int last,int lastest,int sum) { int j,c,maxf,maxs; ans=(ans+(a[now]*sum)%10007+(a[now]*a[lastest])%10007)%10007; maxn=max(maxn,a[now]*a[lastest]); j=point[now]; c=0; maxs=maxf=0; while (j!=0) { if (e[j]!=last) { treedp(e[j],now,last,c); c=(c+a[e[j]])%10007; if (a[e[j]]<=maxf&&a[e[j]]>maxs) maxs=a[e[j]]; if (a[e[j]]>maxf) {maxs=maxf; maxf=a[e[j]];} } j=next[j]; } maxn=max(maxn,maxf*maxs); } int main() { int i,x,y; freopen("linkb.in","r",stdin); freopen("linkb.out","w",stdout); memset(next,0,sizeof(next)); memset(point,0,sizeof(point)); scanf("%d",&n); for (i=1;i<=n-1;++i) { scanf("%d%d",&x,&y); next[i*2-1]=point[x]; point[x]=i*2-1; next[i*2]=point[y]; point[y]=i*2; e[i*2-1]=y; e[i*2]=x; } for (i=1;i<=n;++i) scanf("%d",&a[i]); ans=0; maxn=0; treedp(1,0,0,0); ans=(ans*2)%10007; printf("%d %d",maxn,ans); fclose(stdin); fclose(stdout); }road更简单,dfs判“连通”(考试竟然用floyed..... 60),跑一遍spfa即可 AC CODE:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; struct hp{ int u,v; }a[200001]; int queue[100001],s,t,dis[100001]; int next1[200001],point1[100001],next2[200001],point2[100001],n,m; bool f[100001],ff[100001]; void floodfill(int i) { int j; f[i]=true; j=point1[i]; while (j!=0) { if (f[a[j].v]==false) floodfill(a[j].v); j=next1[j]; } } int spfa() { int head,tail,i,now,vi,y; memset(queue,0,sizeof(queue)); memset(dis,127,sizeof(dis)); memset(f,false,sizeof(f)); head=0; tail=1; queue[tail]=s; y=dis[0]; dis[s]=0; f[s]=true; while (head!=tail) { head=head%100000+1; now=queue[head]; f[now]=false; i=point2[now]; while (i!=0) { vi=a[i].u; if (ff[vi]&&dis[vi]>dis[now]+1) { dis[vi]=dis[now]+1; if (f[vi]==false) { f[vi]=true; tail=tail%100000+1; queue[tail]=vi; } } i=next2[i]; } } if (dis[t]>=y) return -1; else return dis[t]; } int main() { int j,i,x,y; bool d; freopen("roadb.in","r",stdin); freopen("roadb.out","w",stdout); scanf("%d%d",&n,&m); memset(next1,0,sizeof(next1)); memset(point1,0,sizeof(point2)); memset(next2,0,sizeof(next1)); memset(point2,0,sizeof(point2)); memset(f,false,sizeof(f)); memset(ff,false,sizeof(ff)); for (i=1;i<=m;++i) { scanf("%d%d",&x,&y); next1[i]=point1[y]; point1[y]=i; next2[i]=point2[x]; point2[x]=i; a[i].v=x; a[i].u=y; } scanf("%d%d",&s,&t); floodfill(t); for (i=1;i<=n;++i) { d=f[i]; j=point2[i]; while (j!=0) { d=d&&f[a[j].u]; j=next2[j]; } ff[i]=d; } printf("%d\n",spfa()); fclose(stdin); fclose(stdout); }---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Day1 T3完全背包,Day2 T3各种乱搞 代码未写。。。。。。
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
总结:
1.加强对动归的练习 2.多了解一些数论知识 3.要建立起合适的数学模型,力求降低时间复杂度(前提是算对大O......)