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的更多相关文章

  1. 迷宫问题bfs, A Knight's Journey(dfs)

    迷宫问题(bfs) POJ - 3984   #include <iostream> #include <queue> #include <stack> #incl ...

  2. Three Pieces CodeForces - 1065D (BFS)

    链接 大意: n*n棋盘, 每个格子写有数字, 各不相同, 范围[1,n*n], 初始在数字1的位置, 可以操纵knight,bishop,rook三种棋子, 每走一步花费1, 交换棋子花费1, 问按 ...

  3. 记录----第一次使用BFS(广度搜索)学习经验总结

    学习经验记录与分享—— 最近在学习中接触到了一种解决最短路径的实用方法----BFS(广度搜索),在这里总结并分享一下第一次学习的经验. 首先第一个要了解的是"queue"(队列函 ...

  4. zju 1091

    // Traveling Knight Problem #include "stdafx.h" #include <string> #include <strin ...

  5. x01.xiangqi: 走动棋子

    采用 pygame 写的象棋程序,目前只完成绘制棋盘与走动棋子,还没考虑规则等问题. 1. 代码: """ x01.xiangqi (c) 2019 by x01&quo ...

  6. [JLOI2008]将军

    Description 刘先生最近在学习国际象棋,使用一个叫"jloi-08"的游戏软件.在这个游戏里,不但可以和电脑普通地对弈,还可以学习著名的棋局,还有针对初学者的规则指导等丰 ...

  7. c++ 广度优先搜索(宽搜)

    c++ bfs基本应用 Knight Moves 题目描述 贝茜和她的表妹在玩一个简化版的国际象棋.棋盘如图所示: 贝茜和表妹各有一颗棋子.棋子每次移一步,且棋子只能往如图所示的八个方向移动.比赛的规 ...

  8. HDU 1372 Knight Moves (bfs)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1372 Knight Moves Time Limit: 2000/1000 MS (Java/Othe ...

  9. HDU 1372 Knight Moves【BFS】

    题意:给出8*8的棋盘,给出起点和终点,问最少走几步到达终点. 因为骑士的走法和马的走法是一样的,走日字形(四个象限的横竖的日字形) 另外字母转换成坐标的时候仔细一点(因为这个WA了两次---@_@) ...

随机推荐

  1. 安装CocoaPods流程及常见问题(Xcode->homebrew->RVM->Ruby->CocoaPods)

    一.HomeBrew 1.(转)HomeBrew的安装和简单使用 http://blog.csdn.net/maojudong/article/details/7918291 2.homebrew的简 ...

  2. noip2015Day2T2-子串

    题目描述 Description 有两个仅包含小写英文字母的字符串A和B.现在要从字符串A中取出k个互不重叠的非空子串,然后把这k个子串按照其在字符串A中出现的顺序依次连接起来得到一个新的字符串,请问 ...

  3. Windows上安装MongoDB步骤

    事前准备: 1.在mongoDB官网下载.msi文件,我下的是社区版,下载地址:https://www.mongodb.com/download-center#community 2.点击msi文件安 ...

  4. iOS开发关于xcode中souceControl的苹果文档翻译(节选)

    Subversion 1.7 provides many benefits: svn1.7版本有以下好处: Improved performance. Increased speed for many ...

  5. 转Rollback后undo到底做了些什么?

    转自:http://biancheng.dnbcw.info/oracle/309191.html Rollback后undo到底做了些什么? 从概念上讲,undo正好与redo相对.当你对数据执行修 ...

  6. LeetCode OJ 120. Triangle

    Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent n ...

  7. UltraEdit 中的常用正则表达式

    正则表达式 (UltraEdit Syntax):   % 匹配行首 - 表明要搜索的字符串一定在行首.   $ 匹配行尾 - 表明要搜索的字符串一定在行尾   ? 匹配除换行符外的任一单个字符.   ...

  8. MSXML insertBefore(IXMLDOMNode *newChild, VARIANT refChild) 传参

    在xml操作中经常会用到在某一个节点后或前面插入一个节点,MSXML DOM 中使用的函数是insertBefore(IXMLDOMNode *newChild, VARIANT refChild): ...

  9. window.showModalDialog()的简单用法

    //创建一个显示html内容的模态对话框: vReturnValue = window.showModalDialog(sURL [, vArguments] [,sFeatures]) //创建一个 ...

  10. Python 学习笔记8

    在最想放弃的时候 想想美好的事情 想想明天. 今天继续看错误与异常. http://www.pythondoc.com/pythontutorial3/errors.html