您的位置:首页 > 其它

HDU:4255 A Famous Grid(构造+BFS)

2015-04-18 14:31 417 查看
题意:给一个表,问两个位置之间的最短距离是多少,其中素数位置不能经过。

思路:坐标范围是10000,也就是说这个表大约是100*100,当然题目中表是无穷大的,由于有些位置不能走实际上可能会大于100*100。这样构造一个大点的表判断一下素数位置,每次查询直接bfs求最短路即可。

#include <iostream>
#include <string>
#include <cstring>
#include <cctype>
#include <cstdio>
#include <map>
#include <stack>
#include <cmath>
#include <queue>
#include <algorithm>
#define UP 0
#define DOWN 1
#define LEFT 2
#define RIGHT 3
using namespace std;
const int maxn=410;
int g[maxn][maxn];
int vis[maxn][maxn];
const int mov[4][2]= {{-1,0},{1,0},{0,-1},{0,1}};
bool isPrime(int v)
{
    int ed=sqrt(v);
    for(int i=2; i<=ed; ++i)
        if(v%i==0) return false;
    return true;
}
int nextDir(int d)
{
    if(d==RIGHT) return UP;
    else if(d==UP) return LEFT;
    else if(d==LEFT) return DOWN;
    else if(d==DOWN) return RIGHT;
}
pair<int,int> pos[10005];
void init()
{

    int val=0;
    int x=200,y=200;
    g[x][y]=++val;
    pos[val]=make_pair(x,y);
    int d=RIGHT;
    int len=2;
    while(len<=105)
    {
        for(int i=1; i<len; ++i)
        {
            x=x+mov[d][0];
            y=y+mov[d][1];
            ++val;
            if(isPrime(val)) g[x][y]=0;
            else
            {
                g[x][y]=val;
                if(val<=10000)
                    pos[val]=make_pair(x,y);
                }
        }
        d=nextDir(d);
        for(int i=1; i<len; ++i)
        {
            x=x+mov[d][0];
            y=y+mov[d][1];
            ++val;
            if(isPrime(val)) g[x][y]=0;
            else
            {
                g[x][y]=val;
                if(val<=10000)
                    pos[val]=make_pair(x,y);
                }

        }
        d=nextDir(d);
        ++len;
    }

}

int bfs(int st,int ed)
{

    memset(vis,0,sizeof(vis));
    queue<pair<int,int> > que;
    que.push(pos[st]);
    while(!que.empty())
    {
        pair<int,int> p=que.front();
        que.pop();
        for(int i=0; i<4; ++i)
        {
            int nx=p.first+mov[i][0],ny=p.second+mov[i][1];
            if(vis[nx][ny]||g[nx][ny]==0) continue;
            vis[nx][ny]=vis[p.first][p.second]+1;
            if(g[nx][ny]==ed) return vis[nx][ny];
            que.push(make_pair(nx,ny));
        }
    }
    return -1;
}
int main()
{
    init();
    int x,y,kase=0;
    while(scanf("%d%d",&x,&y)!=EOF)
    {
        printf("Case %d: ",++kase);
        if(x==y) printf("0\n");
        else
        {
            int ans=bfs(x,y);
            if(ans==-1) puts("impossible");
            else printf("%d\n",ans);
        }
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: