spiral grid
时间限制:
2000 ms | 内存限制:
65535 KB
难度:
4
-
描述
-
Xiaod 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. In addition, traveling from a prime number is disallowed, either. 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.
-
输入
- Each test case is described by a line of input containing two nonprime integer 1 <=x, y<=10,000. 输出
- For each test case, display its case number followed by the length of the shortest path or "impossible" (without quotes) in one line. 样例输入
-
1 4 9 32 10 12
样例输出
-
Case 1: 1 Case 2: 7
Case 3: impossible
-
解释一下题目,就是在图中的质数是不可以走的,然后给你起点,给你终点,输出最小步数。
-
首先看到问题就是要怎么构建这个二维数组,也就是这个要走的地图,看前100的样例,自然是和蛇形填数有关 系,也就是倒着从10000开始进行填数。
-
其次,就是要在二维数组中标记质数,用普通的方法去判断质数进行标记,时间会比较长,但是nyoj上的时间限度还是可以水过的,但是更快一点的方法就是筛选进行标记,会节省很多的时间。还有就是标记的时候可以给标记质数自己单设置一个一位数组,这样可以免去类似数组清0一样的回复原状态的工作,同样节省了时间。
-
另外要注意的就是广搜和标记了,没什么好说的啦~~
-
用素数筛选的代码:
-
勇敢的贴一下没改进的代码:#include <stdio.h> #include <iostream> #include <stdlib.h> #include <string.h> #include <math.h> #include <queue> #define MAX 101 using namespace std; int map[MAX][MAX]; //创建的地图 int vis[MAX][MAX]; //用于标记走过的路线 int Prime[10001]; //用于质数的标记 int row = 100, col = 100; //用于蛇形填数,先将行和列都设置成100 int num; struct node { int x; int y; int step; }; const int flag[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; void IndexPrime(int num) //筛选标记质数,我在初始化的时候把数组全部初始化成1,不是质数的为0 { Prime[0] = 0; Prime[1] = 0; for(int i=2; i<=sqrt(num); i++) { for(int j=i+1; j<=num; j++) { if(j%i == 0) Prime[j] = 0; //不是质数是0 } } } void tianshu(int num) //蛇形填数 num为填数的圈数 100行100列,就是50圈 { int k = col * row; int i, j; for(i=1; i<=num; i++) { for(j=i; j<=col; j++) { map[i][j] = k--; } for(j=i+1; j<=row; j++) { map[j][col] = k--; } for(j=col-1; j>=i; j--) { map[row][j] = k--; } for(j=row-1; j>i; j--) { map[j][i] = k--; } col--; //每填完一圈,col-1,row-1; row--; } } int a, b; int s_x, s_y; int bfs() { queue <node> Q; node start, p; start.x = s_x; start.y = s_y; start.step = 0; Q.push(start); vis[start.x][start.y] = 1; while(!Q.empty()) { p = Q.front(); Q.pop(); node q; for(int i=0; i<4; i++) { q.x = p.x + flag[i][0]; q.y = p.y + flag[i][1]; q.step = 0; if(q.x>=1 && q.x<=100 && q.y>=1 && q.y<=100 && vis[q.x][q.y]!=1 && !Prime[map[q.x][q.y]]) { if(map[q.x][q.y] == b) { q.step = p.step + 1; return q.step; } else if(map[q.x][q.y]!=b && vis[q.x][q.y]!=1) { q.step = p.step + 1; Q.push(q); vis[q.x][q.y] = 1; } } } } return -1; } int main() { num = 50; tianshu(num); //创建蛇形填数的图 int i, j; int cont = 1; memset(Prime, 1, sizeof(Prime)); //把标记质数的数组初始化成1 IndexPrime(10000); while(scanf("%d%d", &a, &b)!=EOF) { memset(vis, 0, sizeof(vis)); for(i=1; i<=100; i++) { for(j=1; j<=100; j++) { if(map[i][j] == a) { s_x = i; s_y = j; } } } int result = bfs(); if(result == -1) { printf("Case %d: ", cont); printf("impossible\n"); } else { printf("Case %d: ", cont); printf("%d\n", result); } cont++; } return 0; }
-
另外还是提醒自己一下,要注意数的范围,以及重要的细节问题!!!!#include <stdio.h> #include <iostream> #include <stdlib.h> #include <math.h> #include <queue> #define MAX 101 using namespace std; int map[MAX][MAX]; int vis[MAX][MAX]; int row = 100, col = 100; int num; struct node { int x; int y; int step; }; const int flag[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; int IfPrime(int number) //普通的质数判断 { if(number < 2) return 0; for(int i=2; i<=sqrt(number); i++) { if(number%i == 0) return 0; } return 1; } void tianshu(int num) { int k = col * row; int i, j; for(i=1; i<=num; i++) { for(j=i; j<=col; j++) { map[i][j] = k--; } for(j=i+1; j<=row; j++) { map[j][col] = k--; } for(j=col-1; j>=i; j--) { map[row][j] = k--; } for(j=row-1; j>i; j--) { map[j][i] = k--; } col--; row--; } } int a, b; int s_x, s_y; int bfs() { queue <node> Q; node start, p; start.x = s_x; start.y = s_y; start.step = 0; Q.push(start); while(!Q.empty()) { p = Q.front(); Q.pop(); node q; for(int i=0; i<4; i++) { q.x = p.x + flag[i][0]; q.y = p.y + flag[i][1]; q.step = 0; if(q.x>=1 && q.x<=100 && q.y>=1 && q.y<=100 && vis[q.x][q.y]!=1) { if(map[q.x][q.y] == b) { q.step = p.step + 1; return q.step; } else if(map[q.x][q.y]!=b && vis[q.x][q.y]!=1) { q.step = p.step + 1; Q.push(q); vis[q.x][q.y] = 1; } } } } return -1; } int main() { num = 50; tianshu(num); int i, j; int cont = 1; while(scanf("%d%d", &a, &b)!=EOF) { for(i=1; i<=100; i++) { for(j=1; j<=100; j++) { if(map[i][j] == a) { s_x = i; s_y = j; } } } for(i=1; i<=100; i++) //因为改变了标记的值,所以每次都要初始化。。。 { for(j=1; j<=100; j++) { if(IfPrime(map[i][j]) == 1) vis[i][j] = 1; else vis[i][j] = 0; } } int result = bfs(); if(result == -1) { printf("Case %d: ", cont); printf("impossible\n"); } else { printf("Case %d: ", cont); printf("%d\n", result); } cont++; } return 0; }