终于有时间来总结一下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;
}
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Day1 T2,Day2 T2都需要一定的思考
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......)