一. 题目链接:http://poj.org/problem?id=3126
二. 一看就知道广搜,然后还耗费了2个多小时才AC,中间还贡献了一次TLE(忘记标记走过路径)。还看了几天前的博客,好像就是2天前,才记得怎么求最短路径- -!
三. 代码:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <queue>
using namespace std;
const int MAX_SIZE = 9999;
struct node
{
int arr[5];
int time;
friend bool operator < (node a, node b) { return a.time > b.time; }
};
bool primeList[MAX_SIZE + 6];
node start, finish;
bool visited[MAX_SIZE + 1];
void numToArr(int num, int *arr)
{
for(int i = 4; i > 0; i--){
arr[i] = num%10;
num = num/10;
}
}
int ArrToNum(int *arr)
{
int ans = 0;
for(int i = 1; i <= 4; i++)
ans += arr[i]*pow(10, 4-i);
return ans;
}
void buildList()
{
int i, j, nsqrt = sqrt(MAX_SIZE) + 1;
memset(primeList, 0, sizeof(primeList));
for(i = 2; i <= nsqrt; i++)
for(j = 2; j <= MAX_SIZE/i; j++)
primeList[j*i] = true;
}
int bfs()
{
priority_queue <node> que;
node cur, Next;
int i, j, t;
que.push(start);
visited[ArrToNum(start.arr)] = true;
while(!que.empty()){
cur = que.top();
que.pop();
if(ArrToNum(cur.arr) == ArrToNum(finish.arr))
return cur.time;
for(i = 1; i <= 4; i++){
for(j = 0; j < 10; j++){
if(j == cur.arr[i] || 1 == i && 0 == j)
continue;
for(t = 1; t <= 4; t++)
if(t != i)
Next.arr[t] = cur.arr[t];
else
Next.arr[t] = j;
if(visited[i])
continue;
if(primeList[ArrToNum(Next.arr)])
continue;
if(visited[ArrToNum(Next.arr)])
continue;
else
visited[ArrToNum(Next.arr)] = true;
Next.time = cur.time + 1;
que.push(Next);
}
}
}
return -1;
}
int main()
{
//freopen("in.txt", "r", stdin);
buildList();
int T, startNumber, finishNumber;
cin>>T;
while(T--){
cin>>startNumber>>finishNumber;
numToArr(startNumber, start.arr);
numToArr(finishNumber, finish.arr);
start.time = 0;
memset(visited, 0, sizeof(visited));
int ans = bfs();
if(ans == -1)
cout<<"Impossible"<<endl;
else
cout<<ans<<endl;
}
return 0;
}