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
注意起点可以是素数,蛇形填数+广度搜索
本题用到的技巧
(1)注意蛇形填数,为grid加了一个边框,边框的值为-1,这样生成数字时不用考虑是否越界,在广度搜索时也不用判断是否越界
(2)利用pair<int,int>充当point不用再定义数据结构
(3)在广度搜索时,要确定每层是否已经遍历完,每层遍历完后将Point(0,0)压入队列中作为层与层的分隔#include <iostream> #include <algorithm> #include <vector> #include <utility> #include <queue> using namespace std; typedef pair<int,int> Point; int grid[102][102]={0}; const int dx[] = {0,1,0,-1}; //右,下,左,上 const int dy[] = {1,0,-1,0}; void make_spiral_grid(){ for(int i = 0 ;i < 102; ++ i) grid[0][i]=grid[i][0]=grid[101][i]=grid[i][101]= -1; int number =100*100,x = 1,y = 0,step = 0; while(number){ step%=4; while(grid[x+dx[step]][y+dy[step]] == 0){ x+=dx[step];y+=dy[step]; grid[x][y]=number--; } step++; } } bool isPrime(int n){ if(n < 0) return true; if(n == 1) return false; if(n%2 == 0) return (n==2); if(n%3 == 0) return (n==3); if(n%5 == 0) return (n==5); for(int i = 7; i*i <= n; i+=2 ){ if(n%i == 0) return false; } return true; } Point getPointFromGrid(int v){ for(int i = 1; i <= 100; i++){ for(int j = 1; j <= 100; j++){ if(grid[i][j] == v) return Point(i,j); } } return Point(0,0); } int bfs(int startV,int endV){ vector<vector<bool> > visit(102,vector<bool>(102,false)); Point startPoint = getPointFromGrid(startV); queue<Point> points; points.push(startPoint); visit[startPoint.first][startPoint.second] = true; points.push(Point(0,0)); int step = 1; while(!points.empty()){ Point a = points.front(); points.pop(); if(a.first == 0 && a.second == 0) { if(points.empty()) break; points.push(a); step++; continue; } for(int i = 0 ; i < 4; ++ i){ int newx = a.first + dx[i]; int newy = a.second + dy[i]; if(grid[newx][newy]==endV) return step; if(!isPrime(grid[newx][newy]) && !visit[newx][newy]) { points.push(Point(newx,newy)); visit[newx][newy] = true; } } } return 0; } int main(){ make_spiral_grid(); int icase = 0,x,y; while(cin >> x >> y){ if(isPrime(y)) cout<<"Case "<<++icase<<": impossible"<<endl; else if(x == y ) cout<<"Case "<<++icase<<": 0"<<endl; else{ int res = bfs(x,y); if(res == 0) cout<<"Case "<<++icase<<": impossible"<<endl; else cout<<"Case "<<++icase<<": "<<res<<endl; } } }