avatar
fireworks99
keep hungry keep foolish

POJ 3126 Prime Path

Description

给出两个素数,求从这个变到那个需要几步。(变法:每步仅改变一位数)

题目链接 http://poj.org/problem?id=3126

Code

#include <set>
#include <map>
#include <queue>
#include <cstdio>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int inf = 0x3f3f3f3f;

int tot;
int prime[1500];
bool vis[10500];
bool flag[10500];

struct node
{
    int val, step;
};
queue<node> q;

void get_prime()
{
    memset(vis, 1, sizeof(vis));
    tot = 0;
    vis[0] = vis[1] = 0;
    for(int i = 2; i < 10410; ++i)
    {
        if(vis[i])
            prime[++tot] = i;///下面的 j<= tot 决定了这里从1开始存
        for(int j = 1; j <= tot && prime[j] * i <= 10100; ++j)
        {
            vis[ prime[j] * i ] = 0;
            if(i % prime[j] == 0)
                break;
        }
    }
}

///起初这里写了形参队列q,结果在此函数内q不是全局内的q
void seek(node now, node nxt, int t)
{
    if(!flag[t] && vis[t])///未访问过且为素数
    {
        flag[t] = 1;
        nxt.val = t;
        nxt.step = now.step + 1;
        q.push(nxt);
    }
}

int bfs(int a, int b)
{
    while(q.size())
        q.pop();
    memset(flag, 0, sizeof(flag));
    node now, nxt;
    now.val = a;
    now.step = 0;
    flag[a] = 1;
    q.push(now);
    while(q.size())
    {
        now = q.front();
        q.pop();
        if(now.val == b)
            return now.step;
        int t;
        for(int i = 1; i <= 9; i += 2)///个位换奇数
        {
            t = now.val / 10 * 10 + i;
            seek(now, nxt, t);
        }
        for(int i = 0; i <= 9; ++i)///十位
        {
            t = (now.val / 100 * 10 + i) * 10 + now.val % 10;///此处及后面同位置易出错
            seek(now, nxt, t);
        }
        for(int i = 0; i <= 9; ++i)///百位
        {
            t = (now.val / 1000 * 10 + i) * 100 + now.val % 100;
            seek(now, nxt, t);
        }
        for(int i = 1; i <= 9; ++i)///千位
        {
            t = i * 1000 + now.val % 1000;
            seek(now, nxt, t);
        }
    }
    return inf;
}

int main()
{
    get_prime();
    int t, a, b;
    cin >> t;
    while(t--)
    {
        scanf("%d%d", &a, &b);
        int ans = bfs(a, b);
        if(ans != inf)
            cout << ans << '\n';
        else
            cout << "Impossible" << '\n';
    }
    return 0;
}
Site by Baole Zhao | Powered by Hexo | theme PreciousJoy