POJ——3126Prime Path(双向BFS+素数筛打表)
| 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.
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
Output
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[N],prime[N];
int color[N];
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;
}
POJ——3126Prime Path(双向BFS+素数筛打表)的更多相关文章
- poj3126Prime Path  (BFS+素数筛)
		素数筛:需要一个数组进行标记 最小的素数2,所有是2的倍数的数都是合数,对合数进行标记,然后找大于2的第一个非标记的数(肯定是素数),将其倍数进行标记,如此反复,若是找n以内的所有素数,只需要对[2, ... 
- poj 3048 Max Factor(素数筛)
		这题就是先写个素数筛,存到prime里,之后遍历就好,取余,看是否等于0,如果等于0就更新,感觉自己说的不明白,引用下别人的话吧: 素数打表,找出20000之前的所有素数,存入prime数组,对于每个 ... 
- [poj] 2549 Sumsets || 双向bfs
		原题 在集合里找到a+b+c=d的最大的d. 显然枚举a,b,c不行,所以将式子移项为a+b=d-c,然后双向bfs,meet int the middle. #include<cstdio&g ... 
- HDU - 4548-美素数 (欧拉素数筛+打表)
		小明对数的研究比较热爱,一谈到数,脑子里就涌现出好多数的问题,今天,小明想考考你对素数的认识. 问题是这样的:一个十进制数,如果是素数,而且它的各位数字和也是素数,则称之为"美素数&quo ... 
- POJ 3126 Prime Path (BFS + 素数筛)
		链接 : Here! 思路 : 素数表 + BFS, 对于每个数字来说, 有四个替换位置, 每个替换位置有10种方案(对于最高位只有9种), 因此直接用 BFS 搜索目标状态即可. 搜索的空间也不大. ... 
- poj 1077 Eight(双向bfs)
		题目链接:http://poj.org/problem?id=1077 思路分析:题目要求在找出最短的移动路径,使得从给定的状态到达最终状态. <1>搜索算法选择:由于需要找出最短的移动路 ... 
- POJ_3126 Prime Path 【BFS+素数打表】
		一.题目 http://poj.org/problem?id=3126 二.分析 该题主要是要让我们找到一个$4$位素数到另一个$4$位素数的最少的变换次数,且要求保证每一次变换都满足 1.下一个数必 ... 
- Uva 1599 Ideal Path - 双向BFS
		题目连接和描述以后再补 这题思路很简单但还真没少折腾,前后修改提交了七八次才AC...(也说明自己有多菜了).. 注意问题: 1.看清楚原题的输入输出要求,刚了书上的中文题目直接开撸,以为输入输出都是 ... 
- Codeforces_776B: Sherlock and his girlfriend(素数筛)
		题目链接 题意:对2~n+1染色,一个数不能与其素因子同色. 故而只需两种颜色即可,素数染1,合数染2便可满足条件 #include<bits/stdc++.h> using namesp ... 
随机推荐
- be seen doing和be seen to do的区别
			1. be seen doing和be seen to do的区别 be seen doing表被看到正在做某事:be seen to do 表被看到做某事(不表进行) He was seen to ... 
- GetDC(),ReleaseDC()
			用GetDC()得到的DC, 必须调用ReleaseDC()用CreateDC()创建的DC, 必须调用DeleteDC() 两者是不能混淆的.一种典型的错误代码如下:CDC* pDC = GetDC ... 
- Fragment(一)--Fragment用法常见问题
			fragment notes fragment相关内容包括 基本定义与使用 回退栈内部实现 fragment通信(与activity 与fragment) DialogFragment VP + Fr ... 
- div+css 布局经验 - 最简单的 = 最不变形的(原创技巧)
			站酷几年了 一直饱受其恩泽 尤为感激 一直想奉献些什么 但是苦于水平 苦于奔波 今天静下心来 为大家奉献下 自己的div+css 经验 ,以下观点只代表 深海个人立场 希望为初学者提供一条" ... 
- 【Web应用-大文件部署】上传超过 2M 的文件到 Azure PHP 网站失败
			问题描述 上传超过 2M 的文件到 Azure PHP 网站失败. 问题分析 由于 PHP 本身默认上传文件的上限是 2M,所以当上传超过2M的文件时会报错. 解决方法 根据以下步骤进行配置: 在 s ... 
- jmeter中文件上传配置
- Clown without borders 2017/1/9
			原文 Taking laughter to those who need it most "When will you all return again?"the Croatian ... 
- HDU 1693 Eat the Trees (插头DP)
			题意:给一个n*m的矩阵,为1时代表空格子,为0时代表障碍格子,问如果不经过障碍格子,可以画一至多个圆的话,有多少种方案?(n<12,m<12) 思路: 这题不需要用到最小表示法以及括号表 ... 
- js  判断是什么浏览器、是否为谷歌浏览器
			<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta http ... 
- mac文件夹怎么重命名?苹果电脑文件夹重命名快捷键
			windows系统下给文件夹重命名相信很多朋友都很熟悉,那么Mac OS系统怎么给文件重命名呢,相信很多刚刚入手Mac OS系统的亲们都会有次疑问,下面小编告诉你Mac OS系统的文件夹到底要怎样才能 ... 
