Time Limit: 5000MS | Memory Limit: 65536K | |
Total Submissions: 16057 | Accepted: 3892 |
Description
Input
Output
Sample Input
5 6 4 4 1 4 2 3 2 3 1 3 2 3 3 3 3 4 4 4 4 2 3 1 3 1 4 2 4 4 2 1 2 2 3 4 4 2 0 0 0
Sample Output
Case 1: 9 Case 2: -1
Hint
Source
//思路就是简单的bfs,但是蛇的状态不好表示,vis[21][21][1<<14]中 //前两维表示蛇头的位置,后一维中的二进制中每两位表示蛇身体相对于 //前一节身体的方向,正好0,1,2,3四个数表示四个方向。这样就可以把蛇的 //状态标识出来了。 //代码略挫,清楚思路就好。 #include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; int n,m,l,k,mp[25][25]; int dir[3][3]={-1,1,-1,3,-1,2,-1,0,-1}; int D[4][2]={1,0,-1,0,0,1,0,-1}; bool vis[21][21][1<<14]; struct Body{ int x[10],y[10]; int cnt; }body,bb; bool chak(int a,int b,Body c){ for(int i=2;i<=l;i++){ if(a==c.x[i]&&b==c.y[i]) return true; } return false; } int bfs(){ queue<Body>q; body.cnt=0; q.push(body); while(!q.empty()){ body=q.front();q.pop(); if(body.x[1]==1&&body.y[1]==1) return body.cnt; for(int i=0;i<4;i++){ int x=body.x[1]+D[i][0],y=body.y[1]+D[i][1]; if(x<1||x>n||y<1||y>m||mp[x][y]) continue; if(chak(x,y,body)) continue; body.x[0]=x;body.y[0]=y; int sta=0,tmp1,tmp2; for(int j=l;j>=1;j--){ bb.x[j]=body.x[j-1];bb.y[j]=body.y[j-1]; if(j!=l){ tmp1=bb.x[j]-bb.x[j+1]+1; tmp2=bb.y[j]-bb.y[j+1]+1; int tmp=dir[tmp1][tmp2];tmp=(tmp<<(14-j*2)); if(dir[tmp1][tmp2]!=-1) sta=(sta|tmp); } } if(vis[x][y][sta]) continue; vis[x][y][sta]=1; bb.cnt=body.cnt+1; q.push(bb); } } return -1; } int main() { int cas=0,x,y; while(scanf("%d%d%d",&n,&m,&l)&&n&&m&&l){ memset(mp,0,sizeof(mp)); memset(vis,0,sizeof(vis)); int sta=0; scanf("%d%d",&body.x[1],&body.y[1]); for(int i=2;i<=l;i++){ scanf("%d%d",&body.x[i],&body.y[i]); x=body.x[i-1]-body.x[i]+1; y=body.y[i-1]-body.y[i]+1; int tmp=dir[x][y];tmp=(tmp<<(14-(i-1)*2)); if(dir[x][y]!=-1) sta=(sta|tmp); } vis[body.x[1]][body.y[1]][sta]=1; scanf("%d",&k); for(int i=0;i<k;i++){ scanf("%d%d",&x,&y); mp[x][y]=1; } printf("Case %d: %d\n",++cas,bfs()); } return 0; }
原文:http://www.cnblogs.com/--ZHIYUAN/p/6675481.html