ACM spiral grid

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;
        }
    }
}

 

 
posted @ 2014-04-26 18:52  OpenSoucre  阅读(191)  评论(0编辑  收藏  举报