POJ-3126 一个素数转换到另一个素数的最短步数

///题意:一个四位素数变到另一个素数最多需要变换(每个位置上的数字变成另一个数,且变换后的数还是素数)多少次
///一个是暴力的写法,一个是bfs(暴力);大概的意思都是把每一个数的个十百千分别提取出来
///然后进行除了本身的几种变换 然后每次记录到达中途某个数的步数,直到该数字等于所给数为止;
/*
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=1e4+7;
int n,m,prime[maxn],a[maxn],b[maxn];
void ac(int n,int m)
{
    int temp,t,t1;
    a[n]=1;b[0]=n;t=0;t1=1;
    while(a[m]==0&&t<t1)
    {
        temp=b[t]/10*10;
        for(int i=0;i<10;i++)
        {
            if(prime[temp+i]==0&&a[temp+i]==0)
            {
                a[temp+i]=a[b[t]]+1;
                b[t1++]=temp+i;
            }
        }
        temp=b[t]/100*100+b[t]%10;
        for(int i=0;i<10;i++)
        {
             if(prime[temp+10*i]==0&&a[temp+10*i]==0)
             {
                 a[temp+10*i]=a[b[t]]+1;
                 b[t1++]=temp+10*i;
             }
        }
        temp=b[t]/1000*1000+b[t]%100;
        for(int i=0;i<10;i++)
        {
            if(prime[temp+100*i]==0&&a[temp+100*i]==0)
            {
                a[temp+100*i]=a[b[t]]+1;
                b[t1++]=temp+100*i;
            }
        }
        temp=b[t]%1000;
        for(int i=1;i<10;i++)
        {
            if(prime[temp+1000*i]==0&&a[temp+1000*i]==0)
            {
                a[temp+1000*i]=a[b[t]]+1;
                b[t1++]=temp+1000*i;
            }
        }
        t++;
    }
    if(a[m]==0) printf("Impossible\n");
    else printf("%d\n",a[m]-1);
}
int main()
{
    int t;
    memset(prime,0,sizeof(prime));
    prime[0]=prime[1]=1;
    for(int i=2;i<=maxn;i++)
    {
        if(!prime[i])
        {
            for(int j=i*i;j<=maxn;j+=i)
                prime[j]=1;
        }
    }
    scanf("%d",&t);
    while(t--)
    {
        int n,m;
        memset(a,0,sizeof(a));
        scanf("%d %d",&n,&m);
        ac(n,m);
    }
    return 0;
}*/
///bfs()的写法;心中有多少cnm want to say 这个题居然稳稳的卡我素数的判断,我也是很盲目的自信了一回,
///然而到了后来我把每一个素数的判断值输出来时,,我顿时傻逼了, 卡了几个钟头的东西 还是素数没写对,cccccc
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;

const int maxn=1e4+7;

int cnt=0,first,last,ans[maxn];
bool vis[maxn],prime[maxn];

void getprime()
{
    int i,j;
    for(i=1000;i<=maxn;i++)
    {
        for(j=2;j<i;j++)
            if(i%j==0){prime[i]=false;break;}
        if(j==i) prime[i]=true;
    }
}

int bfs()
{
    memset(vis,0,sizeof(vis));
    memset(ans,0,sizeof(ans));
    queue<int>Q;
    int a[5],temp,temp1,now;
    Q.push(first);
    vis[first]=1;
    while(!Q.empty())
    {
        now=Q.front();
        Q.pop();
        if(now==last) return ans[now];
        a[0]=now/1000;
        a[1]=(now/100)%10;
        a[2]=(now/10)%10;
        a[3]=now%10;
        for(int i=0;i<4;i++)
        {
            temp=a[i];
            for(int j=0;j<10;j++)
            {
                if(j!=temp)
                {
                    a[i]=j;
                    temp1=a[0]*1000+a[1]*100+a[2]*10+a[3];
                    if(prime[temp1]&&!vis[temp1])
                    {
                        ans[temp1]=ans[now]+1;
                        vis[temp1]=1;
                        Q.push(temp1);
                    }
                    if(temp1==last) return ans[temp1];
                }
            }
            a[i]=temp;
        }
    }
    return -1;
}

int main ()
{
    getprime();
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d %d",&first,&last);
        int ans=bfs();
        if(ans==-1) printf("Impossible\n");
        else printf("%d\n",ans);
    }
    return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值