题目描述:

有一个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. Django框架和前端的的基本结合

    1 昨日回顾 a socket b 路由关系 c 模板字符串替换(模板语言) 主流web框架总结: django a用别人的 b自己写的 c自己写的 flask a用别人的 b自己写的 c用别人的(j ...

  2. PHP-PHPExcel用法详解

    以下文章来源:diandian_520 http://blog.csdn.net/diandian_520/article/details/7827038 1.header header(" ...

  3. java冒泡排序和快速排序代码

    冒泡排序: package nicetime.com; //基本思想:在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,// 让较大的数往下沉,较小的往上 ...

  4. codevs 2277 爱吃皮蛋的小明(水题日常)

    时间限制: 1 s  空间限制: 32000 KB  题目等级 : 白银 Silver 题目描述 Description 小明特别爱吃蛋,特别是皮蛋.他一次可以吃一个蛋或者两个蛋(整个吞下去),而且他 ...

  5. Cannot fetch index base URL https://pypi.python.org/pypi/ 解决方法

    vi /etc/resolv.conf # Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8) # ...

  6. 2012-2013 ACM-ICPC, NEERC, Central Subregional Contest C Sequence (打表)

    打个表找找规律,到24445的时候乘2以后产生了0出现循环. 一般地,判断循环节是否存在可以用Floyd判圈算法. #include<bits/stdc++.h> using namesp ...

  7. (五)VMware Harbor 部署之SSL

    转自:https://www.cnblogs.com/Rcsec/p/8479728.html 1 .签名证书与自签名证书 签名证书:由权威颁发机构颁发给服务器或者个人用于证明自己身份的东西. 自签名 ...

  8. 历史管理 onhashchange

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. JavaWeb项目实现图片验证码

    一.什么是图片验证码? 可以参考下面这张图: 我们在一些网站注册的时候,经常需要填写以上图片的信息. 这种图片验证方式是我们最常见的形式,它可以有效的防范恶意攻击者采用恶意工具,调用“动态验证码短信获 ...

  10. OpenCV2:直方图

    一.简介 在一个单通道的灰度图像中,每个像素的值介于0(黑色)~255(白色)之间,灰色图像的直方图有256个条目(或称为容器)