POJ 3278 Catch That Cow(追赶母牛)
2015-12-21 16:39
330 查看
题目链接:POJ 3278
题意:
给出两个数字n,k。每次在一个位置p可选择先前走1步到达p+1,或者先前走p步到达2*p,或向后走一步到达p-1。问最少需要多少次移动可以从0出发到达k?
例如n=5,k=17时,最短的移动路径是:0-->5-->10-->9-->18-->17,记为4次。
思路:
用BFS搜索。每次从队列首取出一个所到达的位置,判断该位置是不是目标位置,如果不是的话,然后从该位置有三种方案选择下一位置,将符合条件的方案(剪枝)压入队列(如果不是目标位置)。开两个数组,一个用于记录该位置是否已经访问过,一个用于记录到达该位置的步骤数。
题意:
给出两个数字n,k。每次在一个位置p可选择先前走1步到达p+1,或者先前走p步到达2*p,或向后走一步到达p-1。问最少需要多少次移动可以从0出发到达k?
例如n=5,k=17时,最短的移动路径是:0-->5-->10-->9-->18-->17,记为4次。
思路:
用BFS搜索。每次从队列首取出一个所到达的位置,判断该位置是不是目标位置,如果不是的话,然后从该位置有三种方案选择下一位置,将符合条件的方案(剪枝)压入队列(如果不是目标位置)。开两个数组,一个用于记录该位置是否已经访问过,一个用于记录到达该位置的步骤数。
#include <cstdio> #include <iostream> #include <cstring> #include <queue> using namespace std; const int maxn = 100010; queue<int> q; int step[maxn]; bool vis[maxn]; int n, k; int nextn, head; int bfs() { q.push(n); step = 0; vis = 1; while (!q.empty()) { head = q.front();//去队列首元素 q.pop(); for (int i = 0;i < 3;i++) {//每次有三种选择,nextn是下一次位置 if (i == 0) nextn = head - 1; else if (i == 1) nextn = head + 1; else nextn = head * 2; if(nextn > maxn || nextn < 0) continue;//剪枝,否则队列内元素太多了 if (!vis[nextn])//该位置尚未被访问过 { q.push(nextn); step[nextn] = step[head] + 1; vis[nextn] = 1; } if (nextn == k) return step[nextn];//到达目标位置 } } return -1; } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); #endif while(cin>>n>>k) { memset(vis, 0, sizeof(vis)); if (n >= k) cout << n - k << endl; else cout << bfs() << endl; } return 0; }
相关文章推荐
- ARM下的国密SM3软实现遇到的坑
- 多元统计分析及R语言建模-第6章 判别分析
- BeagleBone Black开发环境
- linux系统的时间调整
- TexLive下使用resumecls中/英文简历模板(Ubuntu 12.04)
- CXF学习笔记一(CXF发布与调用WebService)
- Linux实践篇--linux软件的安装,更新与卸载
- QWebView和js交互
- Linux实践篇--linux软件的安装,更新与卸载
- 内存管理
- ajax之cors跨域
- java中jar包内的类访问jar包内部的资源文件的路径问题
- JAVA过滤器,实现登陆权限限制
- Hibernate 数据的批量插入、更新和删除
- 支付宝如何给存折转账
- unity3d 扩展NGUI Tweener —— TweenTime
- 3DTouch--2
- python 中的使用re 正则表达式处理文字
- javascript通过class获取元素
- 数据结构:二叉搜索树(BST)的基本操作