hdu4255 A Famous Grid(素数表+BFS)
A Famous Grid
Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 172 Accepted Submission(s): 64
Problem Description
Mr. B has recently discovered the grid named "spiral grid".
Construct the grid like the following figure. (The grid is actually infinite. The figure is only a small part of it.)
Considering traveling in it, you are free to any cell containing a composite number or 1, but traveling to any cell containing a prime number is disallowed. You can travel up, down, left or right, but not diagonally. Write a program to find the length of the shortest path between pairs of nonprime numbers, or report it's impossible.
Construct the grid like the following figure. (The grid is actually infinite. The figure is only a small part of it.)
Considering traveling in it, you are free to any cell containing a composite number or 1, but traveling to any cell containing a prime number is disallowed. You can travel up, down, left or right, but not diagonally. Write a program to find the length of the shortest path between pairs of nonprime numbers, or report it's impossible.
Input
Each test case is described by a line of input containing two nonprime integer 1 <=x, y<=10,000.
Output
For each test case, display its case number followed by the length of the shortest path or "impossible" (without quotes) in one line.
Sample Input
1 4
9 32
10 12
Sample Output
Case 1: 1
Case 2: 7
Case 3: impossible
Source
题意:在一个无穷大的蛇形矩阵中,以素数为墙,构成一个图,输入两个合数求这两个合数之间的最短路。
分析:第一步:打素数表;
第二步:构造蛇形地图;(注意地图大小要大于10000)
第三步:BFS求解。
View Code
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<queue> 5 #define N 40400 6 #define MAX 210 7 #define CNT 4000 8 9 using namespace std; 10 11 bool isprime[N]; 12 int prime[CNT],cnt; 13 int map[MAX][MAX]; 14 bool visited[MAX][MAX]; 15 struct point{int x,y,step;}; 16 17 void find_prime() 18 { 19 int i,j; 20 cnt=0; 21 memset(isprime,true,sizeof(isprime)); 22 isprime[1]=false; 23 for(i=2;i<N;i++) 24 { 25 if(isprime[i]) 26 { 27 prime[cnt++]=i; 28 for(j=2*i;j<N;j=j+i) isprime[j]=false; 29 } 30 } 31 } 32 33 void build_map(int p,int q,int s,int c) 34 { 35 if(s==0) return ; 36 int i; 37 for(i=q;i<q+c;i++) map[p][i]=s--; 38 for(i=p+1;i<p+c;i++) map[i][q+c-1]=s--; 39 for(i=q+c-2;i>q;i--) map[p+c-1][i]=s--; 40 for(i=p+c-1;i>p;i--) map[i][q]=s--; 41 build_map(p+1,q+1,s,c-2); 42 } 43 44 int t_i,t_j; 45 46 void find(int u) 47 { 48 int i,j; 49 for(i=1;i<=200;i++) 50 { 51 for(j=1;j<=200;j++) 52 { 53 if(u==map[i][j]) 54 { 55 t_i=i;t_j=j; 56 return ; 57 } 58 } 59 } 60 } 61 62 int BFS(int u,int v) 63 { 64 find(u); 65 point t,tt; 66 t.x=t_i;t.y=t_j;t.step=0; 67 queue<point>Q; 68 while(!Q.empty()) Q.pop(); 69 Q.push(t); 70 visited[t.x][t.y]=true; 71 while(!Q.empty()) 72 { 73 t=Q.front();Q.pop(); 74 if(map[t.x][t.y]==v) return t.step; 75 if(t.x-1>=1&&!visited[t.x-1][t.y]&&!isprime[map[t.x-1][t.y]]) 76 { 77 tt.x=t.x-1;tt.y=t.y;tt.step=t.step+1; 78 Q.push(tt); 79 visited[tt.x][tt.y]=true; 80 } 81 if(t.x+1<=200&&!visited[t.x+1][t.y]&&!isprime[map[t.x+1][t.y]]) 82 { 83 tt.x=t.x+1;tt.y=t.y;tt.step=t.step+1; 84 Q.push(tt); 85 visited[tt.x][tt.y]=true; 86 } 87 if(t.y-1>=1&&!visited[t.x][t.y-1]&&!isprime[map[t.x][t.y-1]]) 88 { 89 tt.x=t.x;tt.y=t.y-1;tt.step=t.step+1; 90 Q.push(tt); 91 visited[tt.x][tt.y]=true; 92 } 93 if(t.y+1<=200&&!visited[t.x][t.y+1]&&!isprime[map[t.x][t.y+1]]) 94 { 95 tt.x=t.x;tt.y=t.y+1;tt.step=t.step+1; 96 Q.push(tt); 97 visited[tt.x][tt.y]=true; 98 } 99 } 100 return 0; 101 } 102 103 int main() 104 { 105 int u,v,k=1; 106 memset(map,0,sizeof(map)); 107 find_prime(); 108 build_map(1,1,40000,200); 109 while(scanf("%d%d",&u,&v)!=EOF) 110 { 111 memset(visited,false,sizeof(visited)); 112 int ans; 113 ans=BFS(u,v); 114 if(ans) printf("Case %d: %d\n",k++,ans); 115 else printf("Case %d: impossible\n",k++); 116 } 117 return 0; 118 }