POJ——3126Prime Path(双向BFS+素数筛打表)
2016-06-30 20:32
148 查看
Prime Path
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
Sample Output
单向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;
}
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 16272 | Accepted: 9195 |
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;
}
相关文章推荐
- 图论算法(5) --- 双向广搜求最短路(Bidirectional Breadth First Search)
- poj1915~双向bfs和bfs
- poj2243~双向bfs
- ACM-BFS之Open the Lock——hdu1195(双向BFS)
- hdoj-2612-find a way-双向BFS
- POJ 3126 Prime Path 解题报告(BFS & 双向BFS)
- hdu 1195 Open the Lock
- 双搜其实并不难
- poj1915之双向广搜
- F - Nightmare Ⅱ HDU - 3085——双向BFS
- poj 2243 bfs(172ms)或者双向bfs(94ms)
- [LeetCode] Word Ladder
- Java中的Set、List、Map的用法与区别
- java web 经典博客
- android 实现View的背景色渐变动画
- 模型化理解单调队列优化和斜率优化DP
- hibernate hibernate.cfg.xml component 组件
- 努力,坚持,相信自己…
- 4.2.二维数组和它的指针
- android删除一个view中的子view