pku1324贪吃蛇 进制描述状态

来源:互联网 发布:武汉软件定制开发 编辑:程序博客网 时间:2024/04/30 00:11

        题意:就是给你一个蛇的初始状态,一些障碍物,问最少多少步头到达(1,1)这个点?

       分析:蛇的长度最长为8,最多有20*20个方格,对于每条蛇,如果我们记录它的头结点的位置与前面结点相对于后面的转向(上,下,左,右四种),那么蛇的位置就唯一了。所以总的状态为20*20*4^(8-1),对于每个头的位置,必须还要保存后面身子的转向(因为头不能转向身子,所以身子的位置不同,状态就不同)。空间不会超,直接开个bool数组来标记状态是否走过即可。

       所犯错误:这题做了好几天,着实犯了很多错误:1、开始以为状态只有20*20尴尬  2、没细算,以为空间会超,所以将每个头的位置开个链接表保存出现的状态(因为很多状态是根本到不了的,所以可能比直接开bool数组空间小),这样会MLE 3、保存转向的时候,起始状态,算的是蛇的后面结点相对前面结点的转向,而后面走时,我算的又是蛇的前面结点相对后面结点的转向,orz   4、用的是模拟队列,我找到一种到达的情况就直接跳出了,根本没有把这个状态入队,而外面判-1只是判head?=tail,所以就有可能多输出-1。

#include<stdio.h>#include<iostream>#include<queue>#include<vector>using namespace std;const int maxm=4000000;struct station{int x[8],y[8],step,no;}p,p1,q[maxm];int n,m,l;int next[4][2]={{-1,0},{1,0},{0,-1},{0,1}};bool flag[110][110],tag[410][20000];bool NOTIN(int x,int y)//是不是在规定的范围内{if(x<0||x>=n) return true;if(y<0||y>=m) return true;return false;}int main(){int i,j,k,kk,t=1,u,v,ii,head,tail;bool ok;while(scanf("%d%d%d",&n,&m,&l)!=EOF){if(!n&&!m&&!l) break;ii=0,kk=1;for(i=0;i<l;i++){scanf("%d%d",&p.x[i],&p.y[i]);p.x[i]--,p.y[i]--;if(i){for(j=0;j<4;j++)//前面相对后面结点的转向if(p.x[i-1]==p.x[i]+next[j][0]&&p.y[i-1]==p.y[i]+next[j][1])break;ii=ii+j*kk;//前面的在低位kk*=4;}}scanf("%d",&k);memset(flag,false,sizeof(flag));memset(tag,false,sizeof(tag));while(k--)//标记障碍物的位置{scanf("%d%d",&u,&v);u--,v--;flag[u][v]=true;}printf("Case %d: ",t++);ok=false;if(p.x[0]==0&&p.y[0]==0){ok=true;printf("0\n");continue;}tag[p.x[0]*m+p.y[0]][ii]=true;head=tail=0;p.no=ii;p.step=0;q[tail++]=p;while(head!=tail){p1=q[head];head=(head+1)%maxm;//if(p1.step>=400) break;for(i=0;i<4;i++){p.x[0]=p1.x[0]+next[i][0];p.y[0]=p1.y[0]+next[i][1];if(NOTIN(p.x[0],p.y[0])||flag[p.x[0]][p.y[0]]) continue;//不在规定范围或有障碍物ii=(p1.no*4+i)%(1<<(2*(l-1)));//状态压缩j=p.x[0]*m+p.y[0];if(tag[j][ii]) continue;tag[j][ii]=true;for(k=1;k<l;k++){if(p.x[0]==p1.x[k]&&p.y[0]==p1.y[k])break;p.x[k]=p1.x[k-1];p.y[k]=p1.y[k-1];}if(k<l) continue;if(p.x[0]==0&&p.y[0]==0){ok=true;printf("%d\n",p1.step+1);break;}p.step=p1.step+1;p.no=ii;q[tail]=p;tail=(tail+1)%maxm;}if(i<4) break;}if(!ok) printf("-1\n");}return 0;}


 

原创粉丝点击