kuangbin专题一 简单搜索 质数路径(POJ-3126)
Prime Path
Time Limit: 1000MS Memory Limit: 65536K
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
题目大意
有多组数据,每组数据给两个质数 A 和 B , 其中 A 为起点,B 为终点,每次操作可以更改某一数位上的数字,且更改之后整个数字仍旧是质数,当然还要保持整个数字一直都是四位数。求质数 A 到质数 B 的最少操作次数。
解题思路
很显然的BFS求最短步数模型,还是很简单的。需要注意的是当枚举到更改的是首位数字且将其更改为0的状态时,需要跳过。对于质数的判断,数字有且仅有四位,所以每次用试除法判断质数应该也是可以的,不过我闲得无聊,写了个线性筛质数,预处理求得所有一万以内的质数。不过一开始我还是翻车了一下,在获取更改后的数字时,我起初想偷懒先将数字转成 string ,然后将某一位改成指定数字,再转回 int ,结果在POJ上居然超时了??!!最后还是老老实实改成用一个临时数组存储每一位数字,更改指定位的数字后再还原的写法。
/* 一切都是命运石之门的选择 El Psy Kongroo */
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<deque>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<cmath>
#include<functional>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<int, pii> piii;
typedef pair<double, double> pdd;
typedef pair<string, pii> psi;
typedef __int128 int128;
#define x first
#define y second
const int inf = 0x3f3f3f3f, mod = 1e9 + 7;
int src, des;
const int N = 1e4;
int dist[N];
int prime[N], cnt;
bool st[N];
void get_primes(){
st[1] = true;
for(int i = 2; i < N; i ++ ){
if(!st[i]) prime[cnt ++ ] = i;
for(int j = 0; prime[j] <= N / i; j ++ ){
st[prime[j] * i] = true;
if(i % prime[j] == 0) break;
}
}
}
int get_n(int num, int digit, int k){
int a[5], idx = 0, res = 0;
while(idx <= 4) a[ ++ idx] = num % 10, num /= 10; //获取每一位数字
a[k] = digit; //更改从个位开始第k个数字
while(idx) res = res * 10 + a[idx -- ]; //还原更改后的数字
return res;
}
int bfs(){
if(src == des) return 0;
memset(dist, -1, sizeof(dist));
queue<int> q; q.push(src);
dist[src] = 0;
while(!q.empty()){
int from = q.front();
q.pop();
for(int k = 1; k <= 4; k ++ )
for(int digit = 0; digit <= 9; digit ++ ){
if(k == 4 && !digit) continue; //如果首位数字改成0 跳过
int to = get_n(from, digit, k);
if(st[to] || dist[to] != -1) continue;
q.push(to);
dist[to] = dist[from] + 1;
if(to == des) return dist[to];
}
}
return -1;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
get_primes(); //预处理筛质数
int T; cin >> T;
while(T -- ){
cin >> src >> des;
int res = bfs();
cout << res << endl;
}
return 0;
}
一切都是命运石之门的选择,本文章来源于博客园,作者:MarisaMagic,出处:https://www.cnblogs.com/MarisaMagic/p/17320297.html,未经允许严禁转载