题目1091:棋盘游戏 -- DFS BFS
来源:互联网 发布:安全防护软件排行 编辑:程序博客网 时间:2024/05/16 04:13
题目1091:棋盘游戏
时间限制:1 秒内存限制:32 兆特殊判题:否提交:1469解决:394
题目描述:
有一个6*6的棋盘,每个棋盘上都有一个数值,现在又一个起始位置和终止位置,请找出一个从起始位置到终止位置代价最小的路径:
1、只能沿上下左右四个方向移动
2、总代价是每走一步的代价之和
3、每步(从a,b到c,d)的代价是c,d上的值与其在a,b上的状态的乘积
4、初始状态为1
每走一步,状态按如下公式变化:(走这步的代价%4)+1。
输入:
第一行有一个正整数n,表示有n组数据。
每组数据一开始为6*6的矩阵,矩阵的值为大于等于1小于等于10的值,然后四个整数表示起始坐标和终止坐标。
输出:
输出最小代价。
样例输入:
1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
0 0 5 5
样例输出:
23
来源:
2005年上海交通大学计算机研究生机试真题
答疑:
解题遇到问题?分享解题心得?讨论本题请访问:http://t.jobdu.com/thread-7814-1-1.html
*这题开始用动态规划会发现不可行,必须用搜索,DFS ,BFS 都需要优化
虽然参考网上的AC了这题, 九度论坛上出题也比较坑。这题本身非常好,作为DFS , BFS 练习 很经典,可以敲上n遍了 。 注意BFS利用 queue,DFS 注意回溯。*
DFS
#include <stdio.h>#include <iostream>using namespace std;int ans;int map[6][6];int stax , stay ,ex, ey;int dir[4][2] ={ { 0, 1 }, { 1, 0 },{ 0, -1 }, { -1, 0 } };bool vis[6][6];void dfs(int x , int y , int sum , int statu){ if(sum < ans) { if(x == ex && y == ey) { ans = sum ; return ; }else{ for (int i = 0; i < 4; i++) // 四个方向 { int tempx = x + dir[i][0]; int tempy = y + dir[i][1]; if ( !vis[tempx][tempy] && tempx >= 0 && tempx < 6 && tempy >= 0 && tempy < 6) { int cost = statu * map[tempx][tempy]; // // 每步(从a,b到c,d)的代价是c,d上的值与其在a,b上的状态的乘积 int sum2 = sum + cost; // 走到下一步的总和 int statu2 = cost % 4 + 1; // 状态按如下公式变化:(走这步的代价%4)+1。 vis[tempx][tempy] = true ; dfs(tempx , tempy , sum2 , statu2); vis[tempx][tempy] = false ; // 回溯 } } } }}int main(){ //freopen("in.txt","r",stdin); int k; cin >> k; while (k--) { for (int i = 0; i < 6; i++) { for (int j = 0; j < 6; j++) { cin >> map[i][j]; vis[i][j] = false; } } ans = 999999999; cin >> stax >> stay >> ex >> ey; // 起点 终点 //vis[stax][stay] = true; // 这里必须注释 是可以回到起点吗 dfs(stax , stay , 0 , 1); printf("%d\n",ans); } return 0;}
BFS
#include <stdio.h>#include <iostream>#include <queue>using namespace std;class Node{public: int x, y, sum, statu;};int ans;int map[6][6];int opt[6][6][5]; //记录最优解,剪枝条件Node start;int ex, ey;int cnt = 0;int dir[4][2] ={ { 0, 1 }, { 1, 0 },{ 0, -1 }, { -1, 0 } };queue<Node> q;void bfs(Node n){ q.push(n);//起始点 入队列 int tempx, tempy, cost; while (!q.empty()) { cnt++; Node tn = q.front(); q.pop(); //opt[tn.x][tn.y] = tn.sum ; for (int i = 0; i < 4; i++) // 四个方向 { tempx = tn.x + dir[i][0]; tempy = tn.y + dir[i][1]; if (tempx >= 0 && tempx < 6 && tempy >= 0 && tempy < 6) //坐标必须合理 { // 每步(从a,b到c,d)的代价是c,d上的值与其在a,b上的状态的乘积 cost = tn.statu * map[tempx][tempy]; /* 如果 这一步 比以前的某一步代价 小 或者 比终点的代价小 才修改该位置 */ if (tn.sum + cost < opt[tempx][tempy][cost % 4 ] && tn.sum + cost < opt[ex][ey][cost % 4 ]) { opt[tempx][tempy][cost % 4] = tn.sum + cost; // 记录最优解 // 构造该节点 Node temp; temp.x = tempx; temp.y = tempy; temp.sum = tn.sum + cost; temp.statu = cost % 4 + 1; // 状态按如下公式变化:(走这步的代价%4)+1。 q.push(temp); // 入队列 } } } }}int main(){ //freopen("in.txt","r",stdin); int k; cin >> k; while (k--) { for (int i = 0; i < 6; i++) for (int j = 0; j < 6; j++) { cin >> map[i][j]; for(int k = 0; k < 4 ; k ++) opt[i][j][k] = 100000; } start.sum = 0; // 起点的总代价为 0 start.statu = 1; // 起点的状态为 1 ans = 100000; cin >> start.x >> start.y >> ex >> ey; // 起点 终点 bfs(start); // bfs for (int i = 0; i < 4; i++) // 代价最小的就是最优解 { if (ans > opt[ex][ey][i]) ans = opt[ex][ey][i]; } cout << ans << endl; } return 0;}
1 0
- 题目1091:棋盘游戏 -- DFS BFS
- 题目1091:棋盘游戏
- 题目1091:棋盘游戏
- DFS和BFS 解棋盘游戏(九度OJ 1091)
- 九度OJ 1091:棋盘游戏 (DP、BFS、DFS、剪枝)
- 九度题目1091:棋盘游戏
- 九度OJ--题目1091:棋盘游戏
- 九度 oj 题目1091:棋盘游戏
- DFS、BFS搜索+题目
- POJ 题目1321 棋盘问题(DFS)
- 1091_棋盘游戏
- poj 1321 棋盘问题 - DFS 2251 Dungeon Master - BFS
- BFS,DFS等搜索题目总结
- 529. Minesweeper 扫雷游戏 DFS BFS
- 九度[1091]-棋盘游戏
- 棋盘游戏
- 棋盘游戏
- 棋盘游戏
- 关于in 和 exist 的区别-------------近期优化sql 语句的时候再次碰到
- Elasticsearch中的动态映射
- 放开了谈论
- 通过新浪天气API获取天气
- mongdb3.0用户验证问题
- 题目1091:棋盘游戏 -- DFS BFS
- tornado环境安装
- Excel小技巧,记下来防止忘记
- linux设备驱动归纳总结(二):模块的相关基础概念
- Spring @Resource、@Autowired、@Qualifier的注解注入及区别
- grunt学习(一)——nodejs入门
- selenium java自动化测试
- oracle存储过程写法
- 根据表中的行创建一个分隔列表