uvaoj 1600 Patrol Robot 10603 Fill BFS
2015-09-01 10:48
363 查看
uvaoj 1600 Patrol Robot
一个巡逻机器人在一个n*m的网格上从左上角(1,1)走到右下角(n,m)。格子中有的地方是空地,用0表示,有的地方是障碍,用1表示。机器人每次可以往相邻的四个方向走,每次这个机器人不能连续穿越k个障碍,也就是说,能连续穿越障碍的最大个数是k,求从起点到终点的最短路径长度。起点和终点保证是空地。在每一个格子,需要用一个三元组(x,y,k)来表示,即在位置(x,y)还可以连续穿越k个障碍,来表示这个状态,因为是bfs,所以,需要用一个三维数组表示这个状态有没有经过,一旦到达这个位置,就说明是最短路,直接返回就行了。
/************************************************************************* > File Name: 1600.cpp > Author: gwq > Mail: gwq5210@qq.com > Created Time: 2015年08月11日 星期二 13时27分33秒 ************************************************************************/ #include <cmath> #include <ctime> #include <cctype> #include <climits> #include <cstdio> #include <cstdlib> #include <cstring> #include <map> #include <set> #include <queue> #include <stack> #include <string> #include <vector> #include <sstream> #include <iostream> #include <algorithm> #define INF (INT_MAX / 10) #define clr(arr, val) memset(arr, val, sizeof(arr)) #define pb push_back #define sz(a) ((int)(a).size()) using namespace std; typedef set<int> si; typedef vector<int> vi; typedef map<int, int> mii; typedef pair<int, int> pii; typedef long long ll; const double esp = 1e-5; #define N 25 int mp , n, m, k, sx, sy, ex, ey, vis ; int dx[] = {-1, 0, 1, 0}; int dy[] = {0, 1, 0, -1}; struct Node { int x, y, s, k; Node(int xx, int yy, int ss, int kk) :x(xx), y(yy), s(ss), k(kk) {} void output(void) { printf("x = %d, y = %d, s = %d, k = %d.\n", s, y, s, k); } bool check(void) { if (x == ex && y == ey) { return true; } else { return false; } } }; int bfs(void) { queue<Node> q; clr(vis, 0); q.push(Node(sx, sy, 0, k)); vis[sx][sy][0] = 1; while (!q.empty()) { Node u = q.front(); q.pop(); //u.output(); if (u.check()) { return u.s; } for (int i = 0; i < 4; ++i) { int nx = u.x + dx[i]; int ny = u.y + dy[i]; int ns = u.s + 1; int nk = mp[nx][ny] ? u.k - 1 : k; if (mp[nx][ny] >= 0 && !vis[nx][ny][nk]) { if (!mp[nx][ny] || (mp[nx][ny] && nk >= 0)) { vis[nx][ny][nk] = 1; q.push(Node(nx, ny, ns, nk)); } } } } return -1; } int main(int argc, char *argv[]) { int t; scanf("%d", &t); while (t--) { scanf("%d%d%d", &n, &m, &k); clr(mp, -1); for (int i = 1; i <= n; ++i) { for (int j = 1; j <= m; ++j) { scanf("%d", &mp[i][j]); } } sx = 1; sy = 1; ex = n; ey = m; printf("%d\n", bfs()); } return 0; }
uvaoj 10603 Fill
倒水问题。给定三个容器,每个容器的容量分别是a,b,c,刚开始的时候,只有第三个容器是满的,其他容器都是空的,现在要求出最少多少倒多少水才能量出一个d升的水,也就是说三个容器任意一个量出了d升水都可以。对于BFS的问题,需要先设计出来状态,可以表示这个状态有没有出现过,出现过的话就不用再进入队列了,因为这里要求倒的水量最少,而不是步数最少,所以用优先队列来取出水量最少的结点扩展。因为还可能d这个水量没有找到,所以我们要穷尽所有的结果,如果遇到了d就停止,否则就记录所有的结果,最后找出一个比d小的水量中最大的。
代码如下:
/************************************************************************* > File Name: 10603.cpp > Author: gwq > Mail: gwq5210@qq.com > Created Time: 2015年08月31日 星期一 18时59分14秒 ************************************************************************/ #include <cmath> #include <ctime> #include <cctype> #include <climits> #include <cstdio> #include <cstdlib> #include <cstring> #include <map> #include <set> #include <queue> #include <stack> #include <string> #include <vector> #include <sstream> #include <iostream> #include <algorithm> #define INF (INT_MAX / 10) #define clr(arr, val) memset(arr, val, sizeof(arr)) #define pb push_back #define sz(a) ((int)(a).size()) using namespace std; typedef set<int> si; typedef vector<int> vi; typedef map<int, int> mii; typedef pair<int, int> pii; typedef long long ll; const double esp = 1e-5; #define N 210 int a, b, c, d, cap[3], vis , ans ; struct Node { int x[3], d; Node() {} Node(int aa, int bb, int cc, int dd) { x[0] = aa; x[1] = bb; x[2] = cc; d = dd; } bool operator <(const Node &v) const { return d > v.d; } }; void solve(void) { clr(vis, 0); clr(ans, -1); priority_queue<Node> pq; Node u(0, 0, c, 0); pq.push(u); vis[0][0] = 1; while (!pq.empty()) { u = pq.top(); pq.pop(); for (int i = 0; i < 3; ++i) { if (ans[u.x[i]] < 0 || ans[u.x[i]] > u.d) { ans[u.x[i]] = u.d; } } if (ans[d] >= 0) { return; } for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { if (i != j && u.x[i] > 0 && u.x[j] < cap[j]) { int amount = min(u.x[i], cap[j] - u.x[j]); Node v(u.x[0], u.x[1], u.x[2], u.d + amount); v.x[i] -= amount; v.x[j] += amount; if (!vis[v.x[0]][v.x[1]]) { vis[v.x[0]][v.x[1]] = 1; pq.push(v); } } } } } } int main(int argc, char *argv[]) { int t; scanf("%d", &t); while (t--) { scanf("%d%d%d%d", &a, &b, &c, &d); cap[0] = a; cap[1] = b; cap[2] = c; solve(); while (d >= 0) { if (ans[d] >= 0) { printf("%d %d\n", ans[d], d); break; } --d; } } return 0; }
相关文章推荐
- nginx内置全局变量及含义
- 【循环列表】之魔术师的扑克牌问题
- python实现八皇后
- Tomcat linux、windows下设置内存及编码
- mySql 时间函数及转换
- dao、pojo、javabean
- 【Cocos2dx】动作监听
- ROS(3):xubuntu xface桌面安装ros&启动gui
- JNI编程指南-第六章 异常
- 面向连接与无连接的区别!
- django 1.8 官方文档翻译: 2-2-3 查找 API 参考
- iOS容易造成循引用的场景
- selenium用java选中ul的最后一个li元素里内容
- POJ2155 Matrix(树状数组)
- 禁止页面在浏览器中打开 只能在微信内核浏览器中打开
- android:windowSoftInputMode属性详解
- nginx-配置文件详细说明
- 统计重复字符串的个数
- 详解Android中AsyncTask的使用
- Hive 笔记(1)