题目描述:

有一个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:棋盘游戏的更多相关文章

  1. 九度OJ 题目1384:二维数组中的查找

    /********************************* * 日期:2013-10-11 * 作者:SJF0115 * 题号: 九度OJ 题目1384:二维数组中的查找 * 来源:http ...

  2. hdu 1284 关于钱币兑换的一系列问题 九度oj 题目1408:吃豆机器人

    钱币兑换问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  3. 九度oj题目&amp;吉大考研11年机试题全解

    九度oj题目(吉大考研11年机试题全解) 吉大考研机试2011年题目: 题目一(jobdu1105:字符串的反码).    http://ac.jobdu.com/problem.php?pid=11 ...

  4. 九度oj 题目1007:奥运排序问题

    九度oj 题目1007:奥运排序问题   恢复 题目描述: 按要求,给国家进行排名. 输入:                        有多组数据. 第一行给出国家数N,要求排名的国家数M,国家号 ...

  5. 九度oj 题目1087:约数的个数

    题目链接:http://ac.jobdu.com/problem.php?pid=1087 题目描述: 输入n个整数,依次输出每个数的约数的个数 输入: 输入的第一行为N,即数组的个数(N<=1 ...

  6. 九度OJ题目1105:字符串的反码

    tips:scanf,cin输入字符串遇到空格就停止,所以想输入一行字符并保留最后的"\0"还是用gets()函数比较好,九度OJ真操蛋,true?没有这个关键字,还是用1吧,还是 ...

  7. 九度oj题目1009:二叉搜索树

    题目描述: 判断两序列是否为同一二叉搜索树序列 输入:                        开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束. 接 ...

  8. 九度oj题目1002:Grading

    //不是说C语言就是C++的子集么,为毛printf在九度OJ上不能通过编译,abs还不支持参数为整型的abs()重载 //C++比较正确的做法是#include<cmath.h>,cou ...

  9. 九度OJ题目1003:A+B

    while(cin>>str1>>str2)就行了,多简单,不得不吐槽,九度的OJ真奇葩 题目描述: 给定两个整数A和B,其表示形式是:从个位开始,每三位数用逗号", ...

随机推荐

  1. Sass基本特性

    Sass扩展/继承@extend 代码的继承,声明方式:.class;调用方式:@extend 如: .btn { border: 1px solid #ccc; padding: 6px 10px; ...

  2. 【读书笔记】构建之法(CH1~CH3)

    人类文明的发展离不开哲学家的思考.科学家的发现和工程师的构建.三个简单的方程式解释了什么是现代软件工程: 1.程序=算法+数据结构 2.软件=程序+软件工程 3.软件企业=软件+商业模式 软件开发的不 ...

  3. 起学习iOS开发专用词汇

    今天的单词分别是: l   Asynchronous  形容词 异步的 n  副词形式: asynchronously 异步地 n  缩写:ASYNC n  反义词:synchronous 形容词同步 ...

  4. static心得

    TextClass text; 吉晨   static注意 只要显式调用一个类的某一个static变量,那么就会连带static块,所有static变量一起调用,哪怕不去new一个对象,这时候已经对这 ...

  5. (十一)mybatis之映射器(select)

    映射器 映射器的主要元素有八种: 元素名称 描述 select 查询语句,可自定义参数 insert 插入语句,执行后返回插入的条数 update 更新语句,执行后返回更新的条数 delete 删除语 ...

  6. 状态压缩---区间dp第一题

    标签: ACM 题目 Gappu has a very busy weekend ahead of him. Because, next weekend is Halloween, and he is ...

  7. codeforces Gym 100338E Numbers (贪心,实现)

    题目:http://codeforces.com/gym/100338/attachments 贪心,每次枚举10的i次幂,除k后取余数r在用k-r补在10的幂上作为候选答案. #include< ...

  8. 常用的 Excel 函数

    概述 Excel 学的好,函数不可少.接下来就了解常用的函数. 首先作下简要说明: 本文的内容大多从网上搜集并加以个人理解整理而来,由于初学,可能会出现错误,如有欢迎指出: 所用演示软件为免费丑陋的 ...

  9. PAT (Advanced Level) Practise - 1096. Consecutive Factors (20)

    http://www.patest.cn/contests/pat-a-practise/1096 Among all the factors of a positive integer N, the ...

  10. 使用Microsoft Hadoop(一)

    To run this program, stage some data in HDFS: 1. create a text file called input.txt that has one in ...