http://acm.hdu.edu.cn/showproblem.php?pid=4255
题意:在一个螺旋网格当中求从一个数到另一个数的最短距离(格子中数字为素数地方不可以走)。
思路:打出一个螺旋网格来,然后在其中进行BFS迷宫求解。
由图可发现每层的左上角的数字都等于该层的行、列数的平方,所以打表时起始点的值就知道了。
#include<cstdio> #include<cstring> #include<queue> using namespace std; #define max_size 120//经过测试发现这里至少得是104,同学说x、y范围是10000以内,但是可能走超过10000的地方(也就是从外面绕),但是要是这样又为何必须是104打底呢?102为何不行?如果有清楚的麻烦留言解释一下,谢谢! struct node//记录坐标与步数 { int x,y,step; }; int map[max_size+1][max_size+1]; int vis[max_size+1][max_size+1]; int dx[4]={0,-1,0,1}; int dy[4]={1,0,-1,0};// int start,end; void build()//构建图 { int tot,x,y; memset(map,0,sizeof(map)); tot=map[x=0][y=0]=max_size*max_size; while(tot>1) { while(y+1<max_size && !map[x][y+1]) map[x][++y]=--tot; while(x+1<max_size && !map[x+1][y]) map[++x][y]=--tot; while(y-1>=0 && !map[x][y-1] map[x][--y]=--tot; while(x-1>=0 && !map[x-1][y] map[--x][y]=--tot; } } bool isPrime[max_size*max_size+1]; inline void getprime ()//打打素数表 { int i,j; int max_number=max_size*max_size; memset(isPrime,true,sizeof(isPrime));// isPrime[0]=false; isPrime[1]=false; for(i=2;i<=max_number;i++) { if(isPrime[i]) { for(j=(i<<1);j<=max_number;j+=i) isPrime[j]=false;// } } } inline struct node find_position(int num)//寻找num的位置 { struct node ret; int i,j; for(i=0;i<max_size;i++) { for(j=0;j<max_size;j++) { if (num==map[i][j]) { ret.x=i; ret.y=j; return ret; } } } // return ret;//默认输入都合法 } int canGo(int x,int y)// { if(x>=0&&x<max_size&&y>=0&&y<max_size&&!vis[x][y]&&!isPrime[map[x][y]]) return 1; else return 0; } int bfs(struct node s) { int i,x,y; struct node now,next; queue<struct node>q; if(isPrime[start]||isPrime[end])//起止点中有素数直接返回-1 return -1; if(start==end)//起止点相同时直接返回0 return 0; q.push(s); while(!q.empty()) { now=q.front(); q.pop(); for(i=0;i<4;i++) { x=now.x+dx[i]; y=now.y+dy[i]; if(canGo(x,y)) { if(map[x][y]==end) return now.step+1; next.x=x; next.y=y; next.step=now.step+1; q.push(next); vis[x][y]=1; } } } return -1; } int main() { int t=1,ans; struct node begin; build(); getprime(); while(scanf("%d %d",&start,&end)==2) { memset(vis,0,sizeof(vis)); begin=find_position(start); begin.step=0; ans=bfs(begin); if(ans==-1) printf("Case %d: impossible\n",t++); else printf("Case %d: %d\n",t++,ans); } return 0; }