九度oj 题目1091:棋盘游戏
- 题目描述:
-
有一个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 做这个题需要用到深度优先搜索或广度优先搜索
对于深度优先搜索而言,其基本思路是从起始点出发,遍历4个方向,一直走下去,直到终点。但要注意如何去剪枝。这里把花费作为参数传入到函数中,作为剪枝的条件。代码如下#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#define inf 0x3f3f3f3f int graph[][];
int dir[][] = { {,},{,},{,-},{-,} };
bool isVisit[][]; int startx, starty, endx, endy;
int ans; void dfs(int nowx, int nowy, int state, int sum) {
if(sum > ans) {
return;
}
if(nowx == endx && nowy == endy) {
ans = sum;
}
for(int i = ; i < ; i++) {
int tempx = nowx + dir[i][];
int tempy = nowy + dir[i][];
if(tempx >= && tempx <= && tempy >= && tempy <= && isVisit[tempx][tempy] == false) {
int cost = state * graph[tempx][tempy];
int stateNext = (cost%) + ;
isVisit[tempx][tempy] = true;
dfs(tempx, tempy, stateNext, sum + cost);
isVisit[tempx][tempy] = false;
} }
} int main(int argc, char const *argv[])
{ int n;
//freopen("input.txt","r",stdin);
scanf("%d",&n);
while(n--) {
for(int i = ; i < ; i++) {
for(int j = ; j < ; j++) {
scanf("%d",&graph[i][j]);
isVisit[i][j] = false;
}
}
scanf("%d %d %d %d",&startx, &starty, &endx, &endy);
ans = inf;
dfs(startx, starty,,);
printf("%d\n", ans);
} return ;
}对于广度优先搜索,需要一个队列将每一层可以到达的点加入到队列中,每一个个点最多只有4种状态。我们用一个数组存这四种状态中每一种状态的最小代价,遍历到终点时四种代价之中的最小者则为最小花费
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <queue>
#define inf 0x3f3f3f3f
using namespace std; int graph[][];
int dir[][] = { {,},{,},{,-},{-,} };
int opt[][][]; int startx, starty, endx, endy;
int ans; struct Node
{
int x;
int y;
int state;
int cost;
}; queue <Node> Q; void bfs(Node start) {
Q.push(start); int tempx, tempy, cost;
while(!Q.empty()) {
Node now = Q.front();
Q.pop();
for(int i = ; i < ; i++) {
tempx = now.x + dir[i][];
tempy = now.y + dir[i][];
if(tempx >= && tempx <= && tempy >= && tempy <= ) {
cost = now.state * graph[tempx][tempy];
int nextState = cost % +;
if(now.cost + cost < opt[tempx][tempy][nextState] && now.cost + cost < opt[endx][endy][nextState]) {
opt[tempx][tempy][nextState] = now.cost + cost;
Node add;
add.x = tempx;
add.y = tempy;
add.state = nextState;
add.cost = now.cost + cost;
// printf("%d %d %d\n",tempx, tempy, add.cost);
Q.push(add);
}
}
}
}
} int main(int argc, char const *argv[])
{ int n;
freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
scanf("%d",&n);
while(n--) {
for(int i = ; i < ; i++) {
for(int j = ; j < ; j++) {
scanf("%d",&graph[i][j]);
for(int k = ; k <= ; k++) {
opt[i][j][k] = inf;
}
}
}
scanf("%d %d %d %d",&startx, &starty, &endx, &endy);
ans = inf;
Node start;
start.x = startx, start.y = starty,start.state = , start.cost = ;
bfs(start);
int min = inf;
for(int i = ; i <= ; i++) {
if(min > opt[endx][endy][i]) {
min = opt[endx][endy][i];
}
}
printf("%d\n", min);
} return ;
}
九度oj 题目1091:棋盘游戏的更多相关文章
- 九度OJ 题目1384:二维数组中的查找
/********************************* * 日期:2013-10-11 * 作者:SJF0115 * 题号: 九度OJ 题目1384:二维数组中的查找 * 来源:http ...
- hdu 1284 关于钱币兑换的一系列问题 九度oj 题目1408:吃豆机器人
钱币兑换问题 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Sub ...
- 九度oj题目&吉大考研11年机试题全解
九度oj题目(吉大考研11年机试题全解) 吉大考研机试2011年题目: 题目一(jobdu1105:字符串的反码). http://ac.jobdu.com/problem.php?pid=11 ...
- 九度oj 题目1007:奥运排序问题
九度oj 题目1007:奥运排序问题 恢复 题目描述: 按要求,给国家进行排名. 输入: 有多组数据. 第一行给出国家数N,要求排名的国家数M,国家号 ...
- 九度oj 题目1087:约数的个数
题目链接:http://ac.jobdu.com/problem.php?pid=1087 题目描述: 输入n个整数,依次输出每个数的约数的个数 输入: 输入的第一行为N,即数组的个数(N<=1 ...
- 九度OJ题目1105:字符串的反码
tips:scanf,cin输入字符串遇到空格就停止,所以想输入一行字符并保留最后的"\0"还是用gets()函数比较好,九度OJ真操蛋,true?没有这个关键字,还是用1吧,还是 ...
- 九度oj题目1009:二叉搜索树
题目描述: 判断两序列是否为同一二叉搜索树序列 输入: 开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束. 接 ...
- 九度oj题目1002:Grading
//不是说C语言就是C++的子集么,为毛printf在九度OJ上不能通过编译,abs还不支持参数为整型的abs()重载 //C++比较正确的做法是#include<cmath.h>,cou ...
- 九度OJ题目1003:A+B
while(cin>>str1>>str2)就行了,多简单,不得不吐槽,九度的OJ真奇葩 题目描述: 给定两个整数A和B,其表示形式是:从个位开始,每三位数用逗号", ...
随机推荐
- Warning: skipping non-radio button in group
Question: 最近在开发中,设计了一个对话框来进行一系列的设定,其中有一组Radio Buttons(单选按钮),但在Debug下,发现对话的弹出有点延迟,经过分析,确定是因为在对话框弹出之 ...
- js获取元素的页面坐标
一.DOM中各种宽度.高度 二.DOM中的坐标系 JS获取div元素的宽度 offsetWidth=width+padding-left+padding-right+border-left+borde ...
- JBOSS连接池默认连接数是多少?在哪个配置文件有这个默认的连接数?
如果你用的是是4.x的Jboss的话,请参考:docs/dtd/jboss-ds_1_0.dtd,相信你很容易就能找到控制最大/最小连接数的选项,应该是诸如:max-pool-size/min-poo ...
- 洛谷 P2910 [USACO08OPEN]寻宝之路Clear And Present Danger
题目描述 Farmer John is on a boat seeking fabled treasure on one of the N (1 <= N <= 100) islands ...
- SQL Server2005的数据还原与备份具体步骤
一:备份数据库步骤 1. 第一步:在开始—>程序(P)—>MicrosoftSQLserver2005—>SQLServerManagementStudio(如下图) 2. 第二步: ...
- (转)SpringMVC学习(五)——SpringMVC的参数绑定
http://blog.csdn.net/yerenyuan_pku/article/details/72511611 SpringMVC中的参数绑定还是蛮重要的,所以单独开一篇文章来讲解.本文所有案 ...
- UVA116 Unidirectional TSP 单向TSP
分阶段的DAG,注意字典序的处理和路径的保存. 定义状态d[i][j]为从i,j 出发到最后一列的最小花费,转移的时候只有三种,向上,向下,或平移. #include<bits/stdc++.h ...
- DAG上的动态规划---嵌套矩形(模板题)
一.DAG的介绍 Directed Acyclic Graph,简称DAG,即有向无环图,有向说明有方向,无环表示不能直接或间接的指向自己. 摘录:有向无环图的动态规划是学习动态规划的基础,很多问题都 ...
- WPF中窗体调用窗体
在WPF中有时候我们需要在一个窗体中去调用另外的一个窗体,下面给出调用方法. 下面实现在MainWindow中通过点击一个按钮调用另外的一个窗口. 首先创建你要调用的另外一个窗口:点击最上面的项目 ...
- winhex 中磁盘大小与偏移
下图为c盘(活动分区).上方base offset为相对于整个硬盘的字节偏移量.partition 1中信息包括c盘开始扇区,总扇区数.partition 2 信息为扩展分区开始扇区和扇区数.由 P1 ...