链接http://poj.org/problem?id=3126
背景:一直WA 感觉完全不知道错在哪里,觉得自己的bfs写的没有错误。。。然后就开始急躁。。去搜了题解。。下次一定要克服这样的心理,要静下心来好好检查每一行代码,不然就会跟上次周赛一样越来越紧张。。要努力去克服!!!!不要总有着想要赶快过题的想法。。。切勿急躁。。
好了。。回到这题。。WA不在bfs而在素数的判定上,,i*i<=t 没有写等号····· 也是自己的知识掌握的不够牢靠。。。
想了一下WA的时候应该先检查逻辑方面或者算法有没有什么问题,如果没有的话就要考虑是否有一些的小问题比如边界条件是小于还是小于等于。。。这些都是要考虑的地方。。平常错误时要先自行排错,检查一个小时,如果实在找不出来的话,干脆先放一放,不要急着去找题解,把题号记下来,过一两天在回来看看能不能找出来,还是不行的话再去参考题解。。
思路主要就是bfs替换各个位置的数字,检查约束条件(是否是素数是否访问过),然后利用bfs就可以找出最小的步数。。
代码:
//poj 3126
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int x,y;
int ok;
int visit[10000];
struct digit
{
int num;
int step;
}cur,next1;
bool is_prime(int t)
{
if(t%2==0) return false;
for(int i = 2;i*i<=t;i++) //i*i <= t!!!!!!!! 漏了小与号结果妥妥的错了。。。
{
if(t%i==0) return false;
}
return true;
}
void bfs(digit temp)
{
temp.step = 0;
queue<digit> q;
q.push(temp);
visit[temp.num] = 1;
while(!q.empty())
{
cur = q.front();
if(cur.num == y)
{
ok = 1;
printf("%d\n",cur.step);
return ;
}
for(int i = 1;i <= 9;i++) //替换千位
{
next1.num = cur.num%1000+i*1000;
next1.step = cur.step + 1;
if(!visit[next1.num]&&is_prime(next1.num))
{
q.push(next1);
visit[next1.num] = 1;
}
}
for(int i = 0;i <= 9;i++) //替换百位
{
next1.num = cur.num%100+i*100+cur.num/1000*1000;
next1.step = cur.step + 1;
if(!visit[next1.num]&&is_prime(next1.num))
{
q.push(next1);
visit[next1.num] = 1;
}
}
for(int i = 0;i <= 9;i++) //替换十位
{
next1.num = cur.num/100*100+i*10+cur.num%10;
next1.step = cur.step + 1;
if(!visit[next1.num]&&is_prime(next1.num))
{
q.push(next1);
visit[next1.num] = 1;
}
}
for(int i = 0;i <= 9;i++) //个位
{
next1.num = cur.num-cur.num%10+i;
next1.step = cur.step + 1;
if(!visit[next1.num]&&is_prime(next1.num))
{
q.push(next1);
visit[next1.num] = 1;
}
}
q.pop();
}
}
int main ()
{
int n;
scanf("%d",&n);
while(n--)
{
ok = 0;
memset(visit,false,sizeof(visit));
scanf("%d %d",&x,&y);
cur.num = x;
bfs(cur);
if(ok == 0)
printf("Impossible\n");
}
return 0;
}