3.11考试

来源:互联网 发布:不教翠羽遇萧峰 知乎 编辑:程序博客网 时间:2024/05/17 07:03

1、贪吃蛇(CJOJ P2185)


第一眼是深搜,于是考场上写了个啥都不加的。。50分

#include<cstdio>#include<algorithm>using namespace std;bool Z[22][22];struct data{int x,y;}que[1001];int hd=1,tl,ans=1000000000;inline int gi(){int x=0;char ch=getchar();while(ch<'0'||ch>'9')ch=getchar();while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();return x;}int n,m;const int X[]={23333,-1,0,1,0},Y[]={333333,0,-1,0,1};inline void dfs(int x,int y,int b){if(b>ans)return;if(x==1&&y==1){ans=b;return;}int tx=que[hd].x,ty=que[hd].y;for(int i=1;i<=4;i++){register int nx=que[tl-1].x+X[i],ny=que[tl-1].y+Y[i];    if(!Z[nx][ny]){    Z[tx][ty]=0,Z[nx][ny]=1;    que[tl]=(data){nx,ny};++hd,++tl;    dfs(nx,ny,b+1);    Z[tx][ty]=1,Z[nx][ny]=0;    --hd,--tl;}}}int main(){    n=gi(),m=gi();    for(int i=1;i<=m;i++)Z[0][i]=Z[n+1][i]=1;    for(int i=1;i<=n;i++)Z[i][0]=Z[i][m+1]=1;    int a,b,l=gi(),k;    tl=l+1;    for(int i=l;i;i--){    que[i].x=gi(),que[i].y=gi();    Z[que[i].x][que[i].y]=1;    }k=gi();    while(k--)a=gi(),b=gi(),Z[a][b]=1;    dfs(que[l].x,que[l].y,0);    printf("%d\n",ans);return 0;} 

经ZJO大神指点,写了个迭代,再加剪枝。。90分。。第9个点S也过不去

#include<cstdio>#include<algorithm>#include<cstring>#include<cstdlib>using namespace std;bool Z[22][22];struct data{int x,y;}que[1001];int hd=1,tl;inline int gi(){int x=0;char ch=getchar();while(ch<'0'||ch>'9')ch=getchar();while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();return x;}int n,m,flag=0;const int X[]={23333,-1,0,1,0},Y[]={333333,0,-1,0,1};inline void dfs(int x,int y,int b,int maxx){if(b==maxx){    if(x==1&&y==1){    printf("%d\n",maxx);    exit(0);    }    return;}if(b+x+y-2>maxx)return;//剪枝int tx=que[hd].x,ty=que[hd].y;for(int i=1;i<=4;i++){register int nx=que[tl-1].x+X[i],ny=que[tl-1].y+Y[i];    if(!Z[nx][ny]){    Z[tx][ty]=0,Z[nx][ny]=1;    que[tl]=(data){nx,ny};++hd,++tl;    dfs(nx,ny,b+1,maxx);    Z[tx][ty]=1,Z[nx][ny]=0;    --hd,--tl;}}}int main(){    n=gi(),m=gi();    for(int i=1;i<=m;i++)Z[0][i]=Z[n+1][i]=1;    for(int i=1;i<=n;i++)Z[i][0]=Z[i][m+1]=1;    int a,b,l=gi(),k;    tl=l+1;    for(int i=l;i;i--){    que[i].x=gi(),que[i].y=gi();    Z[que[i].x][que[i].y]=1;    }k=gi();    while(k--)a=gi(),b=gi(),Z[a][b]=1;    int i;    for(i=1;;i++)dfs(que[l].x,que[l].y,0,i);return 0;}
再加个SPFA与处理出最短距离,再用它来剪枝,过了。。。但个人分析有时也会被卡的没答案,然而数据水还是A了(以下为丑的一比的代码)

#include<cstdio>#include<algorithm>#include<cstring>#include<cstdlib>#include<queue>using namespace std;int Z[22][22];struct data{int x,y;}que[1001];int hd=1,tl,hehe [22][22];inline int gi(){int x=0;char ch=getchar();while(ch<'0'||ch>'9')ch=getchar();while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();return x;}int n,m,flag=0;const int X[]={23333,-1,0,1,0},Y[]={333333,0,-1,0,1};void spfa(){int que[500],in[22][22]={0};for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)    hehe[i][j]=10000000;hehe[1][1]=0;in[1][1]=1;que[1]=0;int hd=1,tl=2;while(hd^tl){int fx=que[hd]/m+1,fy=que[hd]%m+1;for(int i=1;i<=4;i++){int nx=fx+X[i],ny=fy+Y[i];if(Z[nx][ny]!=2&&hehe[nx][ny]>hehe[fx][fy]+1){    hehe[nx][ny]=hehe[fx][fy]+1;    if(!in[nx][ny]){    in[nx][ny]=1;    que[tl++]=(nx-1)*m+ny-1;    if(tl==450)tl=1;}}}hd++;if(hd==450)hd=1;in[fx][fy]=0;}}inline void dfs(int x,int y,int b,int maxx){if(b==maxx){    if(x==1&&y==1){    printf("%d\n",maxx);    exit(0);    }    return;}if(b+hehe[x][y]>maxx)return;int tx=que[hd].x,ty=que[hd].y;for(int i=1;i<=4;i++){register int nx=que[tl-1].x+X[i],ny=que[tl-1].y+Y[i];    if(!Z[nx][ny]){    Z[tx][ty]=0,Z[nx][ny]=1;    que[tl]=(data){nx,ny};++hd,++tl;    dfs(nx,ny,b+1,maxx);    Z[tx][ty]=1,Z[nx][ny]=0;    --hd,--tl;}}}int main(){    n=gi(),m=gi();    for(int i=1;i<=m;i++)Z[0][i]=Z[n+1][i]=1;    for(int i=1;i<=n;i++)Z[i][0]=Z[i][m+1]=1;    int a,b,l=gi(),k;    tl=l+1;    for(int i=l;i;i--){    que[i].x=gi(),que[i].y=gi();    Z[que[i].x][que[i].y]=1;    }k=gi();    while(k--)a=gi(),b=gi(),Z[a][b]=2;    spfa();int i;    for(i=1;;i++)dfs(que[l].x,que[l].y,0,i);return 0;}

2、晨跑路径(CJOJ P1956)


第一眼水题,写了Tarjan

第二眼暴力,果断删了Tarjan,枚举删每一条边(还Tarjan,What a Sabi I am!)

然而还是WA了,链式前向星没乘2。。。(What a Sabi I am!还有为什么这段代码震惊了整个机房)

AC:

#include<cstdio>#include<algorithm>#include<cstring>#define t (dis[i])using namespace std;const int maxn=2010,maxm=8010<<1;int fir[maxn],nxt[maxm],dis[maxm];int n,m;inline void adde(int fr,int to,int id){nxt[id]=fir[fr],fir[fr]=id,dis[id]=to;}inline int gi(){int x=0;char ch=getchar();while(ch<'0'||ch>'9')ch=getchar();while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();return x;}bool vis[maxn];int ans[maxn],Ans=0;inline void dfs(int now){vis[now]=1;for(int i=fir[now];i;i=nxt[i])    if(!vis[t])dfs(t);}int main(){n=gi(),m=gi();int a,b;for(int i=1;i<=m;i++)a=gi(),b=gi(),adde(a,b,i<<1),adde(b,a,i<<1|1);for(int i=2;i<n;i++){memset(vis,0,sizeof vis);vis[i]=1;dfs(1);if(vis[n]==0)ans[++Ans]=i;}printf("%d\n",Ans);for(int i=1;i<=Ans;i++)printf("%d ",ans[i]);return 0;}
3、任务安排(CJOJ P1371)


额啊啊啊DP啊各种单调队列斜率优化什么的都来啦

感谢QT666大神指点,有了这段代码

#include<cstdio>#include<algorithm>#define C(j,i) (F[j]+s*(W[n]-W[j])+T[i]*(W[i]-W[j]))using namespace std;inline int gi(){int x=0;char ch=getchar();while(ch<'0'||ch>'9')ch=getchar();while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();return x;}int T[5011],W[5011];long long F[5011];int n,s;int main(){#ifndef xzz#endifn=gi(),s=gi();for(int i=1;i<=n;i++)T[i]=T[i-1]+gi(),W[i]=W[i-1]+gi();for(int i=1;i<=n;i++){F[i]=C(0,i);    for(int j=1;j<i;j++)    F[i]=min(F[i],C(j,i));}printf("%lld",F[n]);return 0;}



0 0
原创粉丝点击