这题本来是挺简单的,我第一次做没有用素数,后几次没有用四位的素数。本来第一次自己写的时候就是对的,只需要判断一下是不是四位的素数就行,但是居然写了这么久。理解题意真的很重要。。。
改变一个四位数的其中一个数字,有很多办法,可以把它加上或者减去i*1000,i*100,i*10,i*1,i为0到9的整数
R=当前数字%mod。mod分别为10000,1000,100,10。判断R加上对应数值是否是大于0且小于最大值(个位是9,十位是99)
能行就加上或者减去,改变数字,然后再判断条件,虽然有点麻烦,但是挺好操作的。
我后来用了别人的方法,把四位数字存在数组中,这其实并不是重点。重点是我竟然没有判断四位的素数,只有四位的才行啊!!
后来调试看了看它的路径(这倒是个好操作)再看看题,才想明白。
这题就是普通的bfs模板,把能行的点加进队列里就行
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
struct node
{
int v,step,pre;
};//v是数值,step步数,pre储存前一个的数值
node mp[10005];
bool vis[10005],pr[10005];
int st,ed,flag;
void getpr()
{
int i,j;
memset(pr,0,sizeof(pr));
pr[0]=pr[1]=1;
for(i=2;i<=10000;i++)
{
if(!pr[i])
for(j=i*2;j<=10000;j+=i)
pr[j]=1;
}
}//打个素数表
void bfs()
{
queue<node>q;
q.push(mp[st]);
vis[st]=1;
int t[4],temp,i,j,nv;
while(!q.empty())
{
node now=q.front();
q.pop();
//cout<<now.v<<endl;
if(now.v==ed)
{
printf("%d\n",now.step);
flag=1;
break;
}
t[0]=now.v/1000;
t[1]=(now.v/100)%10;
t[2]=(now.v/10)%10;
t[3]=now.v%10;
//怎么让四位数变化一位数字有很多方法,虽然麻烦,小心一点就行
for(i=0;i<=3;i++)
{
temp=t[i];
for(j=0;j<=9;j++)
{
if(temp!=j)
{
t[i]=j;
nv=t[0]*1000+t[1]*100+t[2]*10+t[3];
if(!vis[nv]&&!pr[nv]&&nv>1000)
//是四位的素数,必须要大于1000,找了好久的bug
{
mp[nv].step=now.step+1;
mp[nv].pre=now.v;//记录前一步的
q.push(mp[nv]);
vis[nv]=1;
}
}
}
t[i]=temp;//变回去
}
}
}
int main()
{
int T,i;
scanf("%d",&T);
getpr();
while(T--)
{
scanf("%d%d",&st,&ed);
flag=0;
memset(vis,0,sizeof(vis));
for(i=1;i<=10000;i++)
{
mp[i].pre=i;
mp[i].step=0;
mp[i].v=i;
}
bfs();
//int la=ed;
//for(i=0;i<mp[ed].step;i++)
//{
// cout<<mp[la].pre<<endl;
// la=mp[la].pre;
//}
if(!flag)printf("Impossible\n");
}
return 0;
}