bfs UESTC 381 Knight and Rook
http://acm.uestc.edu.cn/#/problem/show/381
题目大意:给你两个棋子:车、马,再给你一个n*m的网格,从s出发到t,你可以选择车或者选择马开始走,图中有一些障碍物,该障碍物是不能走的,走的图中有换一次棋子的机会,问最少需要几次能从s走到t?
思路:bfs来4次就好了。两次记录从s->t,两次是t->s。然后暴力一下就出来了,复杂度为4*n*m*log
//看看会不会爆int!数组会不会少了一维!
//取物问题一定要小心先手胜利的条件
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define haha printf("haha\n")
const int maxn = + ;
const int inf = 0x3f3f3f3f;
char ch[maxn][maxn];
int n, m;
pair<int, int> s, t;
int rook[maxn][maxn], knight[maxn][maxn];
int r1[maxn][maxn], k1[maxn][maxn];
int r2[maxn][maxn], k2[maxn][maxn];
int dx[] = {-, -, -, , , , , -};
int dy[] = {-, , , , , -, -, -}; int bfs1(int a, int b){
memset(rook, 0x3f, sizeof(rook));
queue<pair<int, int> > que;
que.push(mk(a, b));
rook[a][b] = ;
while (!que.empty()){
pair<int, int> p = que.front(); que.pop();
int x = p.fi, y = p.se;
///if (flag && x == s.fi && y == s.se) break;
int lb = , rb = ;
for (int i = x - ; i > ; i--)
if (ch[i][y] == '#') {lb = i; break;}
for (int i = x; i <= n; i++)
if (ch[i][y] == '#') {rb = i; break;}
if (rb == ) rb = n + ;
///lb和rb都是不能走的
for (int i = lb + ; i < rb; i++){
if (i != x && rook[i][y] > rook[x][y] + ){
rook[i][y] = rook[x][y] + ;
que.push(mk(i, y));
}
}
lb = , rb = ;
for (int i = y - ; i > ; i--)
if (ch[x][i] == '#') {lb = i; break;}
for (int i = y; i <= m; i++)
if (ch[x][i] == '#') {rb = i; break;}
if (rb == ) rb = m + ;
for (int i = lb + ; i < rb; i++){
if (i != y && rook[x][i] > rook[x][y] + ){
rook[x][i] = rook[x][y] + ;
que.push(mk(x, i));
}
}
}
return rook[s.fi][s.se];
} int bfs2(int a, int b){
memset(knight, 0x3f, sizeof(knight));
queue<pair<int, int> > que;
que.push(mk(a, b));
knight[a][b] = ;
while (!que.empty()){
pair<int, int> p = que.front(); que.pop();
int x = p.fi, y = p.se;
///if (flag && x == s.fi && y == s.se) break;
for (int i = ; i < ; i++){
int nx = x + dx[i], ny = y + dy[i];
if (nx <= || ny <= || nx > n || ny > m) continue;
if (ch[nx][ny] == '#') continue;
if (knight[nx][ny] > knight[x][y] + ){
knight[nx][ny] = knight[x][y] + ;
que.push(mk(nx, ny));
}
}
}
return rook[s.fi][s.se];
} int solve(){
//printf("k = %d r = %d\n", k[s.fi][s.se], r[s.fi][s.se]);
//int mini = min(r2[t.fi][t.se], k2[t.fi][t.se]);
int mini = inf;
for (int i = ; i <= n; i++){
for (int j = ; j <= m; j++){
if (ch[i][j] == '#') continue;
if (r1[i][j] < inf && k2[i][j] < inf) mini = min(mini, r1[i][j] + k2[i][j]);
if (k1[i][j] < inf && r2[i][j] < inf) mini = min(mini, k1[i][j] + r2[i][j]);
}
}
if (mini == inf) return -;
return mini;
} int main(){
int T; cin >> T;
for (int kase = ; kase <= T; kase++){
cin >> n >> m;
for (int i = ; i <= n; i++){
scanf("%s", ch[i] + );
for (int j = ; j <= m; j++){
if (ch[i][j] == 's') s = mk(i, j);
if (ch[i][j] == 't') t = mk(i, j);
}
}
memset(r1, inf, sizeof(r1)); memset(k1, inf, sizeof(k1));
memset(r2, inf, sizeof(r2)); memset(k2, inf, sizeof(k2));
bfs1(t.fi, t.se); bfs2(t.fi, t.se);
for (int i = ; i <= n; i++)
for (int j = ; j <= m; j++)
r1[i][j] = rook[i][j], k1[i][j] = knight[i][j];
bfs1(s.fi, s.se); bfs2(s.fi, s.se);
for (int i = ; i <= n; i++)
for (int j = ; j <= m; j++)
r2[i][j] = rook[i][j], k2[i][j] = knight[i][j];
printf("Case #%d: %d\n", kase, solve());
}
return ;
}
bfs UESTC 381 Knight and Rook的更多相关文章
- 迷宫问题bfs, A Knight's Journey(dfs)
迷宫问题(bfs) POJ - 3984 #include <iostream> #include <queue> #include <stack> #incl ...
- Three Pieces CodeForces - 1065D (BFS)
链接 大意: n*n棋盘, 每个格子写有数字, 各不相同, 范围[1,n*n], 初始在数字1的位置, 可以操纵knight,bishop,rook三种棋子, 每走一步花费1, 交换棋子花费1, 问按 ...
- 记录----第一次使用BFS(广度搜索)学习经验总结
学习经验记录与分享—— 最近在学习中接触到了一种解决最短路径的实用方法----BFS(广度搜索),在这里总结并分享一下第一次学习的经验. 首先第一个要了解的是"queue"(队列函 ...
- zju 1091
// Traveling Knight Problem #include "stdafx.h" #include <string> #include <strin ...
- x01.xiangqi: 走动棋子
采用 pygame 写的象棋程序,目前只完成绘制棋盘与走动棋子,还没考虑规则等问题. 1. 代码: """ x01.xiangqi (c) 2019 by x01&quo ...
- [JLOI2008]将军
Description 刘先生最近在学习国际象棋,使用一个叫"jloi-08"的游戏软件.在这个游戏里,不但可以和电脑普通地对弈,还可以学习著名的棋局,还有针对初学者的规则指导等丰 ...
- c++ 广度优先搜索(宽搜)
c++ bfs基本应用 Knight Moves 题目描述 贝茜和她的表妹在玩一个简化版的国际象棋.棋盘如图所示: 贝茜和表妹各有一颗棋子.棋子每次移一步,且棋子只能往如图所示的八个方向移动.比赛的规 ...
- HDU 1372 Knight Moves (bfs)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1372 Knight Moves Time Limit: 2000/1000 MS (Java/Othe ...
- HDU 1372 Knight Moves【BFS】
题意:给出8*8的棋盘,给出起点和终点,问最少走几步到达终点. 因为骑士的走法和马的走法是一样的,走日字形(四个象限的横竖的日字形) 另外字母转换成坐标的时候仔细一点(因为这个WA了两次---@_@) ...
随机推荐
- C# 委托的应用1:将方法作为参数传递给另一个方法[转]
原文:http://blog.csdn.net/susan19890313/article/details/6775461 长期以来,c和c++的程序员利用方法指针,将方法作为参数传给另一个方法.c# ...
- mac下搭建cordova开发环境
Apache Cordova 原名叫PhoneGap.是一个用基于HTML,CSS和JavaScript的,创建移动跨平台移动应用程序的快速开发平台.PhoneGap最初由Nitobi开发,2011年 ...
- Mac笔记本中使用postgresql
安装 brew install postgresql 安装了两个依赖包 ==> Installing dependencies for postgresql: openssl, readline ...
- PRG(Post/Redirect/Get)
转自:PRG(Post/Redirect/Get) 摘要: Post/Redirect/Get 简称PRG,是一种用来防止表单重复提交数据的一种Web设计模式 Post/Redirect/Get 简称 ...
- C# 非public的方法和属性的单元测试
有时候我们写好的类库中,某些类的属性和方法不应该暴露出来,那么如何对这些非public的方法和属性进行单元测试? MS为我们提供了PrivateObject类,可以解决这个问题,可以去MSDN的说明文 ...
- ajax格式,需要指定交互的data类型
思路 先打印所有返回值 console.log(d); {''status'':999} 再查看返回值,能否转换为json dataType:'json', //大小写敏感. datatype ...
- Struts对输入数据的校验
当我们在登录或者是注册时需要对用户输入的数据验证,以前都是浏览器传送数据到后台,后台对数据进行校验,如果有错误就带着错误信息转发带登录或者注册页面, struts可以简便的对输入数据进行校验 首先我们 ...
- Xshell4连接,Linux系统中文显示乱码解决办法
Xshell 是一个强大的安全终端模拟软件,它支持SSH1, SSH2, 以及Microsoft Windows 平台的TELNET NetSarang Xshell 4 Build 0120议.使用 ...
- LeetCode OJ 121. Best Time to Buy and Sell Stock
Say you have an array for which the ith element is the price of a given stock on day i. If you were ...
- Hanoi汉诺塔问题——递归与函数自调用算法
题目描述 Description 有N个圆盘,依半径大小(半径都不同),自下而上套在A柱上,每次只允许移动最上面一个盘子到另外的柱子上去(除A柱外,还有B柱和C柱,开始时这两个柱子上无盘子),但绝不允 ...