1. 程式人生 > >Prime Path POJ - 3126 bfs 暴力

Prime Path POJ - 3126 bfs 暴力

這題求最短路 ,所有的狀態轉移為 9999-999, 不超過10000,最多100個test case, 最壞的時間複雜度為 10e6,絕對不會超時的。

因為求最短路,要麼列舉所有 dfs路徑, 要麼使用 bfs ,不過我同學說求最短路一般bfs要比純dfs快,但是bfs 會消耗更多的記憶體,這題記憶體65536kb,沒有卡記憶體,所以直接暴力bfs。

對於每個四位數, 最多有 9 * 9 * 9 * 9 =6561 種狀態轉移,再加個visit陣列,因為已經訪問過的狀態沒必要在再訪問一遍。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;

const int TOP=1e7+10000;//+10000是為了多篩一個素數
bool e[TOP];
int p[TOP/5];
int pnum;
void prime()//O(n)篩素數,e[x]==0表示x為素數
{
    e[0]=e[1]=1;pnum=0;
    for(int i=2;i<TOP;i++)
    {
        if(e[i]==0)p[++pnum]=i;
        for(int j=1;j<=pnum&&p[j]*i<TOP;j++)
        {
            e[p[j]*i]=1;
            if(i%p[j]==0)break;
        }
    }
}
int vis[10000];

struct node
{
    int p;
    int level;
};
int pos[4] = {10,100,1000,10000};
int bfs(int st1,int en)
{

    if(st1==en)return 0;
    queue<node>  qu;
    node st;
    st.p = st1;
    st.level=0;
    vis[st.p] =1;
    qu.push(st);

    node f;
    node tmp;

    int flag=0;
    while(!qu.empty())
    {
        f = qu.front();
        qu.pop();
        if(f.p == en)
        {
            flag=1;
            break;
        }

       //cout<<f.p<<endl;

        tmp.level = f.level + 1;

        for(int i=0;i<4;i++)
        {
            int base = (f.p - f.p%pos[i]) + f.p%(pos[i]/10);

            for(int j=0;j<=9;j++)
            {
                int now = base + pos[i]/10*j;
               // cout<<base<<"  "<<now<<endl;
                if(vis[now]==0&&now >=1000&&now<10000&&e[now]==0)
                {
                    vis[now] =1;
                    tmp.p = now;
                    qu.push(tmp);
                }
            }
        }
    }
    if(flag==1)
    return f.level;
    else return -1;
}
int main()
{
    ios::sync_with_stdio(false);
    prime();
    int m,n;
    int t;
    cin>>t;
    while(t--)
    {
        cin>>m>>n;
        memset(vis,0,sizeof(vis));
        cout<<bfs(m,n)<<endl;

    }
    return 0;
}