博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Poj 3126 筛法 + bfs (spfa)
阅读量:4217 次
发布时间:2019-05-26

本文共 4905 字,大约阅读时间需要 16 分钟。

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

31033 81791373 80171033 1033

Sample Output

670

 

题目大意:给定两个素数,在每次只能变动一个数字并且变动后的数字仍为素数的前提下,变动到另一个素数需要的最小花费。

 

解法一:  BFS + 改变每一位数字可能情况、

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;const int N = 10000;int step[N];//int base[4] = {1,10,100,1000};int base[4] = {1000,100,10,1};bool vis[N];int d[4];int st,en;bool is_prim[N];void getPrim(){ for(int i = 2; i < N; ++i){ is_prim[i] = true; } for(int i = 2; i < N; ++i){ if(is_prim[i]){ for(int j = 2*i; j < N; j += i){ is_prim[j] = false; } } }}int bfs(int x){ queue
q; q.push(x); vis[x] = true; step[x] = 0; while(!q.empty()){ int cur = q.front(); if(cur == en){ return step[en]; } q.pop(); d[0] = cur/1000; d[1] = cur%1000/100; d[2] = cur%100/10; d[3] = cur%10;// cout << d[3] <<" "<< d[2] <<" "<< d[1] <<" " << d[0] <
> n; while(n--){ cin >> st >> en; memset(vis,false,sizeof(vis)); memset(step,0,sizeof(step)); int ans = bfs(st); if(ans == -1){ cout << "Impossible"<

 

 

解法二:构造素数之间满足条件的无向图 + spfa 求最短路(每条边权重为1)

 

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;const int N = 10000;bool vis[N];bool is_prim[N];int arr1[4],arr2[4];int p = 0;int prim[N];int step[N];int st,en;// 建立素数表void getPrim(){ for(int i = 2; i < N; ++i) is_prim[i] = true; for(int i = 2; i < N; ++i){ if(is_prim[i]){ if(i > 1000){ prim[p++] = i; //把4位的素数保存下来 } for(int j = 2*i; j < N; j += i){ is_prim[j] = false; } } }}// 判断 是否只有一位不同bool check(int x, int y){ arr1[0] = x%10; arr1[1] = x%100/10; arr1[2] = x%1000/100; arr1[3] = x/1000; arr2[0] = y%10; arr2[1] = y%100/10; arr2[2] = y%1000/100; arr2[3] = y/1000; int cnt = 0; for(int i = 0; i < 4; ++i){ if(arr1[i] != arr2[i]) ++cnt; } if(cnt > 1) return false; else return true;}// 满足 只有一位不同的 素数 视为 有边相连void create_graph(vector
adj[]){ for(int i = 0; i < p; ++i){ for(int j = i+1; j < p; ++j){ if(check(prim[i],prim[j])){ adj[i].push_back(j); adj[j].push_back(i); } } }}int spfa(int x,vector
adj[]){ queue
q; q.push(x); vis[x] = true; step[x] = 0; // 首先 初始化为 无穷大 for(int i = 0; i < p; ++i){ step[i] = 1 << 30; } // 起始点初始化为 0 step[x] = 0; while(!q.empty()){ int cur = q.front(); q.pop();// if(cur == en){// mmin = min(mmin,step[cur]);// } for(int i = 0; i < adj[cur].size(); ++i){ int v = adj[cur][i]; if(step[v] > step[cur] + 1){ step[v] = step[cur] + 1; // 如果不在队列 入队 if(!vis[v]){ q.push(v); vis[v] = true; } } } } return step[en];}int main() { ios::sync_with_stdio(false); int n; cin >> n; getPrim(); while(n--){ memset(vis,false,sizeof(vis)); memset(step,0,sizeof(step)); cin >> st >> en; // 把 数据 离散成 0,1,2,3,4.。。 st = lower_bound(prim,prim+p,st)-prim; en = lower_bound(prim,prim+p,en)-prim; vector
adj[N]; create_graph(adj); int ans = spfa(st,adj); if(ans == 1 << 30){ cout << "Impossible"<

 

转载地址:http://uwsmi.baihongyu.com/

你可能感兴趣的文章
《浪潮之巅》3水果公司的复兴
查看>>
《浪潮之巅》4计算机工业的生态链
查看>>
《浪潮之巅》5奔腾的芯 英特尔公司
查看>>
《浪潮之巅》7 互联网的金门大桥 -—思科公司
查看>>
python语言程序设计基础笔记(三)从题目到方案
查看>>
读取txt文件出现出现多余空行问题
查看>>
从理论到实践开发自己的聊天机器人
查看>>
@***装饰器(python)
查看>>
最优化算法之梯度下降法
查看>>
激活函数之ReLU函数
查看>>
经典排序算法详解
查看>>
概述类加载器及类加载过程
查看>>
MySQL SQL优化总结
查看>>
MySQL MyISAM引擎的读锁与写锁
查看>>
面向对象与面向过程的本质的区别
查看>>
Java语言有哪些特点?
查看>>
idea创建maven项目并关联gitee
查看>>
HashMap和Hashtable的区别
查看>>
JVM 对 Java 的原生锁做了哪些优化?
查看>>
JAVA实现简单的阻塞队列
查看>>