题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1973
题目大意 :
每个路口标记为1个四位素数,相邻2个路口只差1个数字,给定初始位置和目标位置,求最少需要多少步到达目标位置。比如初始位置为1033,目的位置8179,最少要走6条街,走法:
1033 ->1733->3733->3739->3779->8779->8179
做法:先素数筛找出所有四位素数,用BFS每次找相邻路口直到找到目标位置或者BFS结束无解。
代码看起来有点长,但是中间大部分代码都是重复的,改一个变量值其它就复制粘贴。
之后有时间再重新改下代码...
#include <cstdio>
#include <queue>
#include <algorithm>
#include <iostream>
#include <cstring>
using namespace std;
int s,e; //起点start和终点end
bool prime[10005]; //素数打表
int step[10005]; //记录步数,比如step[1033]记录走到1033路口花费步数
queue<int> q;
bool vis[10005]; //标记路口是否访问过
int main(){
//素数打表
memset(prime,true,sizeof(prime));
for(int i = 2;i <= 10000;i++){
if(prime[i]){
for(int j = 2*i;j <= 10000;j += i)
prime[j] = false;
}
}
int t;
scanf("%d",&t);
while(t--){
while(!q.empty()) //清空队列
q.pop();
memset(vis,0,sizeof(vis));
memset(step,0,sizeof(step));
scanf("%d%d",&s,&e);
//BFS
vis[s] = 1;
step[s] = 0;
q.push(s);
bool flag = false; //结束标记
while(!q.empty()){ //队列非空
int head = q.front(); //队首
q.pop(); //出队
if(head == e){ //是否结束
printf("%d\n",step[head]);
flag = true;
break;
}
//遍历周围点
int t = head; //临时变量
//个位
int f = t % 10; //first取个位
t -= f; //去掉个位
for(int i = 0;i < 10;i++){ //遍历个位
if(i == f)
continue; //排除自身
t += i;
if(!prime[t]){
t -= i;
continue; //排除非素数
}
if(vis[t]) {
t -= i;
continue;
}
step[t] = step[head] + 1;
q.push(t);
vis[t] = true;
t -= i; //复原
}
t = head;
//十位
f = t/10%10; //first取十位
t -= f*10; //去掉十位
for(int i = 0;i < 10;i++){ //遍历个位
if(i == f)
continue; //排除自身
t += i*10;
if(!prime[t]){
t -= i*10;
continue; //排除非素数
}
if(vis[t]) {
t -= i*10;
continue;
}
step[t] = step[head] + 1;
q.push(t);
vis[t] = true;
t -= i*10; //复原
}
t = head;
//百位
f = t/100%10; //first取百位
t -= f*100; //去掉百位
for(int i = 0;i < 10;i++){ //遍历
if(i == f)
continue; //排除自身
t += i*100;
if(!prime[t]){
t -= i*100;
continue; //排除非素数
}
if(vis[t]){
t -= i*100;
continue;
}
step[t] = step[head] + 1;
q.push(t);
vis[t] = true;
t -= i*100; //复原
}
t = head;
//千位
f = t/1000%10; //first取千位
t -= f*1000; //去掉千位
for(int i = 1;i < 10;i++){ //遍历
if(i == f)
continue; //排除自身
t += i*1000;
if(!prime[t]){
t -= i*1000;
continue; //排除非素数
}
if(vis[t]) {
t -= i*1000;
continue;
}
step[t] = step[head] + 1;
q.push(t);
vis[t] = true;
t -= i*1000; //复原
}
}
if(flag == false) {
printf("impossible!\n");
}
}
return 0;
}