zoukankan      html  css  js  c++  java
  • POJ3126 Prime Path (bfs+素数判断)

    POJ3126 Prime Path

      一开始想通过终点值双向查找,从最高位开始依次递减或递增,每次找到最接近终点值的素数,后来发现这样找,即使找到,也可能不是最短路径,

    而且代码实现起来特别麻烦,后来搜了一下解题报告,才发现是bfs().

      想想也是,题目其实已经提示的很清楚了,求最短的路径,对于每一个数,每次可以把4位中的任意一位,  换成与该位不相同的0-9中的任意一位,对于迷宫类

    bfs每次转移数为上下左右四个状态,而此题就相当于每次可以转移40个状态(其实最低位为偶数可以排除,不过题目数据量较小,就不剪枝了),每次转移的这40个状态,都可能得到最小路径,对于每次转移得到的素数,标记一下used,同时标记一下深度(即所走过的步数)root,从起点m出发,每次进行40个方向的状态转移,直至找到终点n或者队列取空返回无解(-1);

        一开始把rep(j,0,10)写成了rep(j,0,9),wa了半天,这种小细节一定要注意.

    /*
    * Created:     2016年03月30日 08时06分49秒 星期三
    * Author:      Akrusher
    *
    */
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <string>
    #include <vector>
    #include <deque>
    #include <list>
    #include <set>
    #include <map>
    #include <stack>
    #include <queue>
    #include <numeric>
    #include <iomanip>
    #include <bitset>
    #include <sstream>
    #include <fstream>
    using namespace std;
    #define rep(i,a,n) for (int i=a;i<n;i++)
    #define per(i,a,n) for (int i=n-1;i>=a;i--)
    #define in(n) scanf("%d",&(n))
    #define in2(x1,x2) scanf("%d%d",&(x1),&(x2))
    #define inll(n) scanf("%I64d",&(n))
    #define inll2(x1,x2) scanf("%I64d%I64d",&(x1),&(x2))
    #define inlld(n) scanf("%lld",&(n))
    #define inlld2(x1,x2) scanf("%lld%lld",&(x1),&(x2))
    #define inf(n) scanf("%f",&(n))
    #define inf2(x1,x2) scanf("%f%f",&(x1),&(x2))
    #define inlf(n) scanf("%lf",&(n))
    #define inlf2(x1,x2) scanf("%lf%lf",&(x1),&(x2))
    #define inc(str) scanf("%c",&(str))
    #define ins(str) scanf("%s",(str))
    #define out(x) printf("%d
    ",(x))
    #define out2(x1,x2) printf("%d %d
    ",(x1),(x2))
    #define outf(x) printf("%f
    ",(x))
    #define outlf(x) printf("%lf
    ",(x))
    #define outlf2(x1,x2) printf("%lf %lf
    ",(x1),(x2));
    #define outll(x) printf("%I64d
    ",(x))
    #define outlld(x) printf("%lld
    ",(x))
    #define outc(str) printf("%c
    ",(str))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define SZ(x) ((int)(x).size())
    #define mem(X,Y) memset(X,Y,sizeof(X));
    typedef vector<int> vec;
    typedef long long ll;
    typedef pair<int,int> P;
    const int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
    const int INF=0x3f3f3f3f;
    const ll mod=1e9+7;
    ll powmod(ll a,ll b) {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
    const bool AC=true;
    
    bool used[10000];
    int root[10000];
    int s[4];
    bool prime(int n){ //素数测试
        for(int i=2;i*i<=n;i++){
        if(n%i==0) return false;
        }
        return n!=1; //1是例外
    }
    int bfs(int m,int n){ //m相当于起点,n相当于终点,此题就转化为求每次可以走40个方向的迷宫问题的最短距离;
        queue <int> que;
        que.push(m);
        int q,now;
        while(!que.empty()){
        q=que.front();
        que.pop();
        if(q==n) return root[q];
        s[3]=q/1000;s[2]=(q/100)%10;
        s[1]=(q%100)/10;s[0]=q%10;
        rep(i,0,4){  //每次改变4位数中的一位
            rep(j,0,10){  //j>=0&&j<=9,此处不能写成rep(j,0,9);
                if(j!=s[i]){
                    now=q-(s[i]-j)*pow(10,i);
                    if((!used[now])&&(prime(now))&&(now>1000)){ //注意最高为不能是0
                        root[now]=root[q]+1;//步数加1
                        used[now]=true; //标记该素数已被使用
                        que.push(now);
                        }
                    }
                }
            }
        }
     return -1; //从起点m出发所有能够转移到的素数都已用完,没找到解,就返回-1
    }
    int main()
    {
        int t,a,b;
        in(t);
        while(t--){
        in2(a,b);
        fill(used,used+10000,false);
        mem(root,0);
        int ans=bfs(a,b);
        if(ans!=-1) out(ans);
        else printf("Impossible");
        }
        return 0;
    }
  • 相关阅读:
    codeforces 37 E. Trial for Chief【spfa】
    bzoj 1999: [Noip2007]Core树网的核【树的直径+单调队列】
    codehunter 「Adera 6」杯省选模拟赛 网络升级 【树形dp】
    codeforces GYM 100781A【树的直径】
    bzoj 2878: [Noi2012]迷失游乐园【树上期望dp+基环树】
    bzoj 1791: [Ioi2008]Island 岛屿【基环树+单调队列优化dp】
    codeforces 949C
    codeforces 402E
    poj 3613 Cow Relays【矩阵快速幂+Floyd】
    bzoj 2097: [Usaco2010 Dec]Exercise 奶牛健美操【二分+树形dp】
  • 原文地址:https://www.cnblogs.com/akrusher/p/5335955.html
Copyright © 2011-2022 走看看