素数路

题意:

给你两个素数,每次只能改变一个数字并且要求改变后该数字还是素数,问你要迭代几次,如果迭代失败,输出-1。

分析:

这道题,先线性筛得到1000~9999的素数,然后把这些素数当成点建图,如果,两素数仅有一位数字不同,则它们之间有路,然后spfa扫一遍求最短路即可。

#include <iostream>
#include <string>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#define range(i,a,b) for(int i=a;i<=b;++i)
#define rerange(i,a,b) for(int i=a;i>=b;--i)
#define CLSINF(arr) memset(arr,0x7f7f7f7f,sizeof(arr))
#define CLS(arr) memset(arr,0,sizeof(arr))
using namespace std;
int point[10005],cnt=1,s,t,dis[10005];
bool vis[10005];
vector<int>node[10005];
bool judge(int a, int b){
    string A=to_string(a),B=to_string(b);
    int cal=0;
    range(i,0,3)if(A[i]!=B[i])cal++;
    if(cal==1)return true;
    else return false;
}
void init(){
    CLS(point);
    range(i,2,10000)
        if(!vis[i]) {
            if (i > 1000)point[cnt++] = i;
            range(j, 2, 10000 / i)vis[j * i] = true;
        }//建立素数表
    range(i,1,1062)
    range(j,i+1,1062)
    if(judge(point[i],point[j])){
        node[point[i]].push_back(point[j]);
        node[point[j]].push_back(point[i]);
    }//建图
    cin>>s>>t;
}
void spfa(){//最短路
    CLSINF(dis);
    queue<int>q;
    bool inq[10005];
    CLS(inq);
    dis[s]=0;
    q.push(s);
    while(!q.empty()){
        int here=q.front();
        q.pop();
        inq[here]= false;
        range(i,0,node[here].size()-1){
            int next=node[here][i];
            if(dis[next]>dis[here]+1){
                dis[next]=dis[here]+1;
                if(!inq[next]){
                    q.push(next);
                    inq[next]=true;
                }
            }
        }
    }
}
void solve(){
    spfa();
    if(dis[t]==0x7f7f7f7f)cout<<"Impossible"<<endl;
    else cout<<dis[t]<<endl;
}
int main() {
    init();
    solve();
    return 0;
}
View Code

 

posted @ 2018-07-17 15:01  RhythmLian  阅读(198)  评论(0)    收藏  举报