Prime Path(POJ - 3126)【BFS+篩素數】

Z發表於2020-10-02

Prime Path(POJ - 3126)

題目連結

演算法

BFS+篩素數打表

1.題目主要就是給定你兩個四位數的質數a,b,讓你計算從a變到b共最小需要多少步。要求每次只能變1位,並且變1位後仍然為質數。

2.四位數的範圍是1000~9999,之間共有1000多個質數。由於已經知道位數為4位,所以可以通過BFS來尋找最小步數。每次需要分別變換個位、十位、百位、千位,並且把符合要求的數放到佇列中,同時需標記這個數已經遍歷過一次,避免重複遍歷,直到找到目標數。

C++程式碼

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
const int N = 1e4;
int primes[N], cnt;
bool st[N];
bool vis[N];
int t, a, b;
struct Number{
    int data;
    int steps;
};
void get_primes(int n)
{
    for(int i = 2; i <= n; i++)
    {
        if(!st[i]) primes[cnt++] = i;
        for(int j = 0; primes[j] <= n / i; j++)
        {
            st[primes[j]*i] = true;
            if(i % primes[j] == 0) break;
        }
    }
}
void bfs()
{
    queue<Number> que;
    que.push({a, 0});
    vis[a] = true;
    while(que.size())
    {
        Number cur = que.front();
        que.pop();
        if(cur.data == b)
        {
            cout << cur.steps << endl;
            return ;
        }
        Number tmp;
        /*遍歷可能的個位*/
        for(int i = 0; i <= 9; i++)
        {
            tmp.data = cur.data / 10 * 10 + i;
            if(vis[tmp.data] || st[tmp.data]) continue;
            tmp.steps = cur.steps + 1;
            que.push(tmp);
            vis[tmp.data] = true;
        }
        /*遍歷可能的十位*/
        for(int i = 0; i <= 9; i++)
        {
            tmp.data = cur.data / 100 * 100 + i * 10 + cur.data % 10;
            if(vis[tmp.data] || st[tmp.data]) continue;
            tmp.steps = cur.steps + 1;
            que.push(tmp);
            vis[tmp.data] = true;
        }
        /*遍歷可能的百位*/
        for(int i = 0; i <= 9; i++)
        {
            tmp.data = cur.data % 100 + i * 100 + cur.data / 1000 * 1000;
            if(vis[tmp.data] || st[tmp.data]) continue;
            tmp.steps = cur.steps + 1;
            que.push(tmp);
            vis[tmp.data] = true;
        }
        /*遍歷可能的千位*/
        for(int i = 1; i <= 9; i++)
        {
            tmp.data = cur.data % 1000 + i * 1000;
            if(vis[tmp.data] || st[tmp.data]) continue;
            tmp.steps = cur.steps + 1;
            que.push(tmp);
            vis[tmp.data] = true;
        }
    }

}
int main()
{
    get_primes(9999);
    cin >> t;
    while(t--)
    {
        memset(vis, 0, sizeof vis);
        cin >> a >> b;
        bfs();
    }
}

程式碼中使用的線性篩素數模板來源

相關文章