您的位置:首页 > 其它

POJ——3126Prime Path(双向BFS+素数筛打表)

2016-06-30 20:32 148 查看
Prime Path

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 16272 Accepted: 9195
Description


The ministers of the cabinet were quite upset by the message from the Chief of Security stating that they would all have to change the four-digit room numbers on their offices. 

— It is a matter of security to change such things every now and then, to keep the enemy in the dark. 

— But look, I have chosen my number 1033 for good reasons. I am the Prime minister, you know! 

— I know, so therefore your new number 8179 is also a prime. You will just have to paste four new digits over the four old ones on your office door. 

— No, it’s not that simple. Suppose that I change the first digit to an 8, then the number will read 8033 which is not a prime! 

— I see, being the prime minister you cannot stand having a non-prime number on your door even for a few seconds. 

— Correct! So I must invent a scheme for going from 1033 to 8179 by a path of prime numbers where only one digit is changed from one prime to the next prime. 

Now, the minister of finance, who had been eavesdropping, intervened. 

— No unnecessary expenditure, please! I happen to know that the price of a digit is one pound. 

— Hmm, in that case I need a computer program to minimize the cost. You don't know some very cheap software gurus, do you? 

— In fact, I do. You see, there is this programming contest going on... Help the prime minister to find the cheapest prime path between any two given four-digit primes! The first digit must be nonzero, of course. Here is a solution in the case above. 
1033

1733

3733

3739

3779

8779

8179
The cost of this solution is 6 pounds. Note that the digit 1 which got pasted over in step 2 can not be reused in the last step – a new 1 must be purchased.
Input

One line with a positive number: the number of test cases (at most 100). Then for each test case, one line with two numbers separated by a blank. Both numbers are four-digit primes (without leading zeros).
Output

One line for each case, either with a number stating the minimal cost or containing the word Impossible.
Sample Input
3
1033 8179
1373 8017
1033 1033

Sample Output
6
7
0


单向BFS水题,但是双向让我调试了很久,因为写单向的时候是分4种情况,然后想着双向用for来放在一个循环里好了,结果样例输出答案完全不对,只有答案为1或2的时候可能会对,不解一个早上= =刚才想着算了把for去掉写麻烦点,结果又因为忘记删掉调试输出的语句,WA几发。现在还是不知道为什么原来的for是错的。双向BFS给我一个感觉:代码真长(虽然大部分是重复的)嗯这题写完之后上学期遗留的题除了一道题意本身不清楚+大部分AC代码本身也有明显错误的那道题之外全部A掉了。看看专题训练status里我刷了好几页的历史。真是个悲伤的故事……双向的时候要按层搜索

代码:

#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<sstream>
#include<cstring>
#include<cstdio>
#include<string>
#include<deque>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
using namespace std;
#define INF 0x3f3f3f3f
#define MM(x) memset(x,0,sizeof(x))
#define MMINF(x) memset(x,INF,sizeof(x))
typedef long long LL;
const double PI=acos(-1.0);
const int N=10010;
int vis
,prime
;
int color
;
struct info
{
char s[6];
int step;
};
info S,T;
int change(char s[])
{
int r=0;
for (int i=0; i<4; i++)
r=r*10+s[i]-'0';
return r;
}
queue<info>Qf,Qb;
int T_bfs()
{
S.step=0;
T.step=0;
int lay=0;
while (!Qf.empty())
Qf.pop();
while (!Qb.empty())
Qb.pop();
Qf.push(S);
Qb.push(T);
color[change(S.s)]=1;
color[change(T.s)]=2;
while ((!Qf.empty())||(!Qb.empty()))
{
while(!Qf.empty()&&Qf.front().step==lay)
{
info now=Qf.front();
Qf.pop();
info v=now;
while (--v.s[0]>='1')
{
int num=change(v.s);
if(prime[num])
{
if(!color[num])
{
v.step=now.step+1;
color[num]=1;
vis[num]=v.step;
Qf.push(v);
}
else if(color[num]==2)
{
return vis[num]+vis[change(now.s)];
}
}
}

v=now;
while (++v.s[0]<='9')
{
int num=change(v.s);
if(prime[num])
{
if(!color[num])
{
v.step=now.step+1;
color[num]=1;
vis[num]=v.step;
Qf.push(v);
}
else if(color[num]==2)
{
return vis[num]+vis[change(now.s)];
}
}
}

v=now;
while (--v.s[1]>='0')
{
int num=change(v.s);
if(prime[num])
{
if(!color[num])
{
v.step=now.step+1;
color[num]=1;
vis[num]=v.step;
Qf.push(v);
}
else if(color[num]==2)
{
return vis[num]+vis[change(now.s)];
}
}
}
v=now;
while (++v.s[1]<='9')
{
int num=change(v.s);
if(prime[num])
{
if(!color[num])
{
v.step=now.step+1;
color[num]=1;
vis[num]=v.step;
Qf.push(v);
}
else if(color[num]==2)
{
return vis[num]+vis[change(now.s)];
}
}
}

v=now;
while (--v.s[2]>='0')
{
int num=change(v.s);
if(prime[num])
{
if(!color[num])
{
v.step=now.step+1;
color[num]=1;
vis[num]=v.step;
Qf.push(v);
}
else if(color[num]==2)
{
return vis[num]+vis[change(now.s)];
}
}
}
v=now;
while (++v.s[2]<='9')
{
int num=change(v.s);
if(prime[num])
{
if(!color[num])
{
v.step=now.step+1;
color[num]=1;
vis[num]=v.step;
Qf.push(v);
}
else if(color[num]==2)
{
return vis[num]+vis[change(now.s)];
}
}
}

v=now;
while (--v.s[3]>='0')
{
int num=change(v.s);
if(num%2==0)
continue;
if(prime[num])
{
if(!color[num])
{
v.step=now.step+1;
color[num]=1;
vis[num]=v.step;
Qf.push(v);
}
else if(color[num]==2)
{
return vis[num]+vis[change(now.s)];
}
}
}
v=now;
while (++v.s[3]<='9')
{
int num=change(v.s);
if(num%2==0)
continue;
if(prime[num])
{
if(!color[num])
{
v.step=now.step+1;
color[num]=1;
vis[num]=v.step;
Qf.push(v);
}
else if(color[num]==2)
{
return vis[num]+vis[change(now.s)];
}
}
}
}
//
while(!Qb.empty()&&Qb.front().step==lay)
{
info now=Qb.front();
Qb.pop();
info v=now;
while (--v.s[0]>='1')
{
int num=change(v.s);
if(prime[num])
{
if(!color[num])
{
v.step=now.step+1;
color[num]=2;
vis[num]=v.step;
Qb.push(v);
}
else if(color[num]==1)
{
return vis[num]+vis[change(now.s)];
}
}
}

v=now;
while (++v.s[0]<='9')
{
int num=change(v.s);
if(prime[num])
{
if(!color[num])
{
v.step=now.step+1;
color[num]=2;
vis[num]=v.step;
Qb.push(v);
}
else if(color[num]==1)
{
return vis[num]+vis[change(now.s)];
}
}
}

v=now;
while (--v.s[1]>='0')
{
int num=change(v.s);
if(prime[num])
{
if(!color[num])
{
v.step=now.step+1;
color[num]=2;
vis[num]=v.step;
Qb.push(v);
}
else if(color[num]==1)
{
return vis[num]+vis[change(now.s)];
}
}
}

v=now;
while (++v.s[1]<='9')
{
int num=change(v.s);
if(prime[num])
{
if(!color[num])
{
v.step=now.step+1;
color[num]=2;
vis[num]=v.step;
Qb.push(v);
}
else if(color[num]==1)
{
return vis[num]+vis[change(now.s)];
}
}
}
////

v=now;
while (--v.s[2]>='0')
{
int num=change(v.s);
if(prime[num])
{
if(!color[num])
{
v.step=now.step+1;
color[num]=2;
vis[num]=v.step;
Qb.push(v);
}
if(color[num]==1)
{
return vis[num]+vis[change(now.s)];
}
}
}

v=now;
while (++v.s[2]<='9')
{
int num=change(v.s);
if(prime[num])
{
if(!color[num])
{
v.step=now.step+1;
color[num]=2;
vis[num]=v.step;
Qb.push(v);
}
else if(color[num]==1)
{
return vis[num]+vis[change(now.s)];
}
}
}

//

v=now;
while (--v.s[3]>='0')
{
int num=change(v.s);
if(prime[num])
{
if(!color[num])
{
v.step=now.step+1;
color[num]=2;
vis[num]=v.step;
Qb.push(v);
}
else if(color[num]==1)
{
return vis[num]+vis[change(now.s)];
}
}
}

v=now;
while (++v.s[3]<='9')
{
int num=change(v.s);
if(prime[num])
{
if(!color[num])
{
v.step=now.step+1;
color[num]=2;
vis[num]=v.step;
Qb.push(v);
}
else if(color[num]==1)
{
return vis[num]+vis[change(now.s)];
}
}
}
}
lay++;
}
}
int main(void)
{
int tcase,i,j;
for (i=0; i<N; i++)
prime[i]=1;
for (i=2; i<N; ++i)
for (j=2; j*i<N; ++j)
prime[i*j]=0;
scanf("%d",&tcase);
while (tcase--)
{
MM(vis);
MM(color);
scanf("%s%s",S.s,T.s);
if(strcmp(S.s,T.s)==0)
puts("0");
else
printf("%d\n",T_bfs()+1);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  双向BFS