POJ 3126 Prime Path (换门牌)
2015-12-21 16:23
246 查看
题目链接:POJ 3126
题意:
给出两个数a,b,且a,b均为四位素数,a<b。每次只改变a的一位数字,且改变后的数字仍是四位素数(也就是千位不能变为0),经过若干次操作使得最终从a变为b,问最少经历多少次操作?
思路:
先对四位正整数素数打表,然后用BFS搜索,每次从队列首去除一个元素,判断是否是目标数,否则将由这个数产生的符合条件的数字入队列(先判断是否是目标数)。开两个数组,一个用于记录当前数字是否访问过,一个用于记录到达当前数字的步骤数。
题意:
给出两个数a,b,且a,b均为四位素数,a<b。每次只改变a的一位数字,且改变后的数字仍是四位素数(也就是千位不能变为0),经过若干次操作使得最终从a变为b,问最少经历多少次操作?
思路:
先对四位正整数素数打表,然后用BFS搜索,每次从队列首去除一个元素,判断是否是目标数,否则将由这个数产生的符合条件的数字入队列(先判断是否是目标数)。开两个数组,一个用于记录当前数字是否访问过,一个用于记录到达当前数字的步骤数。
#include <iostream> #include <queue> #include <algorithm> #include <cstdio> #include <cstring> #include <sstream> using namespace std; const int maxn = 10000; int IsPrime[maxn],vis[maxn],cnt[maxn]; int n, a, b, ans; int isprime(int n) {//判断n是否为素数 for (int i = 2;i*i <= n;i++) if (n%i == 0) return 0; return 1; } void init() {//对[1000,9999]的正整数进行素数打表 for (int i = 1000;i < maxn;i++) IsPrime[i] = isprime(i); } int BFS(int first,int last) { memset(vis, 0, sizeof(vis));//vis[i]=0表示i尚未访问过 memset(cnt, 0, sizeof(cnt));//cnt[i]表示到达i经历的步骤数 queue<int> q; int v, temp, vtemp, digit[4]; q.push(first);//将起始数入队列 vis[first] = 1;//起始数访问过了 while (!q.empty())//队列非空时 { v = q.front();//取队首元素 q.pop();//队首元素出队列 if (v == last) return cnt[v];//队首元素==目标值,返回次数 digit[0] = v / 1000;//千位 digit[1] = v / 100 % 10;//百位 digit[2] = v / 10 % 10;//十位 digit[3] = v % 10;//个位 for (int i = 0;i < 4;i++) {//对每个数需要改变个十百千每个位上的数字 temp = digit[i]; for (int j = 0;j < 10;j++) {//每个位上的数字从0到9开始替换 if (temp != j) {//数字不重合 digit[i] = j;//这样做方便了计算vtemp! vtemp = digit[0] * 1000 + digit[1] * 100 + digit[2] * 10 + digit[3]; if (vtemp > 999 && !vis[vtemp] && IsPrime[vtemp]) {//千位不为0&&尚未访问过&&是素数 cnt[vtemp] = cnt[v] + 1;//到达vtemp的步骤数=到达v的步骤数+1 vis[vtemp] = 1;//标记访问过 q.push(vtemp);//入队列 } if (vtemp == last) return cnt[vtemp]; } } digit[i] = temp;//别忘记替换回来! } } return -1; } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); #endif init(); while (~scanf("%d", &n)) { while (n--) { scanf("%d%d", &a, &b); ans = BFS(a,b); if (ans == -1) printf("Impossible\n"); else cout << ans << endl; } } return 0; }
相关文章推荐
- 前后端分离的一点实践
- Java线程:线程中断
- IE8打开一个网页出现两个进程的解决方案
- C#(ASP.NET)错误: 无法获取属性“0”的值: 对象为 null 或未定义 关键字 'user' 附近有语法错误。
- LeetCode 10 - Regular Expression Matching
- [leetcode] 37. Sudoku Solver 解题报告
- Android应用实现微信登录与分享
- 好用的文本编缉主题
- iOS: TableView如何刷新指定的cell 或section
- 读书笔记 --《数学之美》_信息的度量和作用
- 应用信息PackageManager
- iOS 7 present/dismiss自定义转场动画
- [Cryptography] Hash Password, Nonce
- 分页处理 jquery ajax
- 《失业的程序员》读后感
- 提取字符串中的数字-非指针版-(C语言描述)
- GitHub
- 数据库设计学习记录
- 信号和槽
- xargs 和 exec