HDU-4255 A Famous Grid BFS

先生成蛇型矩阵,然后再筛选出素数进行标记,最后bfs。这里要注意题目要求的1-10000的之间的数路径,但是并不代表我们只要打印到这个范围的素数,因为很可能边沿的点需要走到外面的图形来完成对短路,外围的也不要打印太多,毕竟素数的个数越到外面是越稀疏的,所以打印到40000足矣。

代码如下:

#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <map>
#define MAXN 40000
using namespace std;

int p[MAXN+5], G[205][205], hash[205][205];

int dist[1005][1005];

int N, M;

struct Node
{
    int x, y;    
}info;

map<int, Node>mp;

struct 
{
    int x, y, step;    
}q[1000005], pos;

int front, tail, dir[4][2] = {-1, 0, 1, 0, 0, 1, 0, -1};

void draw(int cen)
{
    int num = (200 - 2*cen + 2) * (200 - 2*cen + 2)+1;
    int sx = cen, sy = cen;
    for (int j = sy; j < (200 - cen + 1); ++j) {
        G[sx][j] = --num;
        info.x = sx, info.y = j;
        mp[num] = info;
    }
    for (int i = sx; i < (200 - cen + 1); ++i) {
        G[i][(200 - cen + 1)] = --num;
        info.x = i, info.y = (200 - cen + 1);
        mp[num] = info;
    }
    for (int j = (200 - cen + 1); j > sy; --j) {
        G[(200 - cen + 1)][j] = --num;
        info.x = (200 - cen + 1), info.y = j;
        mp[num] = info;
    }
    for (int i = (200 - cen + 1); i > sx; --i) {
        G[i][sy] = --num;
        info.x = i, info.y = sy;
        mp[num] = info;
    }
}

void pre()
{
    int k;
    for (int i = 4; i <= 40000; i += 2) {
        p[i] = 1;
    }
    
    for (int i = 3; i <= 200; i += 2) {
        if (!p[i]) {
            k = 2 * i;
            for (int j = i * i; j <= 40000; j += k) {
                p[j] = 1;
            }
        }
    }
    
    for (int cen = 1; cen <= 200; ++cen) {
        draw(cen);
    }
}

bool judge(int x, int y)
{
    if (x < 1 || x > 200 || y < 1 || y > 200) {
        return false;
    }
    return true;
}

int bfs(int sx, int sy)
{
    int xx, yy;
    front = 0, tail = 1;
    memset(hash, 0, sizeof (hash));
    q[tail].x = sx, q[tail].y = sy;
    q[tail].step = 0;
    hash[sx][sy] = 1;
    while (front != tail) {
        pos = q[++front];
        for (int i = 0; i < 4; ++i) {
            xx = pos.x + dir[i][0];
            yy = pos.y + dir[i][1];
            if (!hash[xx][yy] && judge(xx, yy) && G[xx][yy] != -1) {
                if (N <= 1000 && M <= 1000) {
                    dist[N][G[xx][yy]] = pos.step + 1;
                }
                hash[xx][yy] = 1;
                if (G[xx][yy] == M) {
                    return pos.step + 1;
                }
                ++tail;
                q[tail].x = xx, q[tail].y = yy;
                q[tail].step = pos.step + 1;
            }
        }
    }
    return -1;
}

int main()
{
    int sx, sy, ans, ca = 0;
    p[1] = 1;
    pre();
    for (int i = 2; i <= 40000; ++i) {
        if (!p[i]) {
            G[mp[i].x][mp[i].y] = -1;
        }
    }
    while (scanf("%d %d", &N, &M) == 2) {
        printf("Case %d: ", ++ca);
        if (N == M) {
            puts("0");
            continue;
        }
        if ((N <= 1000 && M <= 1000) && dist[N][M]) {
            printf("%d\n", dist[N][M]);
            continue;
        }
         sx = mp[N].x, sy = mp[N].y;
        ans = bfs(sx, sy);
        
        if (ans != -1) {
             printf("%d\n", ans);
        }
        else {
            puts("impossible");
        }
    }
    return 0;    
}
posted @ 2012-07-16 22:20  沐阳  阅读(382)  评论(0编辑  收藏  举报