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. 新手购买海外VPS主机需要注意的几个账户安全问题

    一般我们用户的项目需要,可能会较多的购买海外的VPS主机项目居多,其实我也比较喜欢国内的阿里云等产品,但是后者需要的一些政策还是比较麻烦, 所以在操作一些调试项目的时候我比较倾向于选择较为便宜的海外V ...

  2. 《Windows编程循序渐进》——建立MFC应用程序

    如何建立MFC应用程序 打开VS2013:

  3. 定时器 QuartZ Cron表达式

    CronTrigger CronTriggers往往比SimpleTrigger更有用,如果您需要基于日历的概念,而非SimpleTrigger完全指定的时间间隔,复发的发射工作的时间表. CronT ...

  4. 实验吧Web-天网管理系统

    笔记 == : 比较运算符号  不会检查条件式的表达式的类型 ===:  恒等计算符 , 同时检查表达式的值与类型.(会检查表达式类型,如bool) PHP序列化与反序列化serialize() 对输 ...

  5. iOS开发传感器相关

    手机里面内置了很多的传感器,例如:光传感器,湿度传感器,温度传感器,距离传感器等等 //开发传感器相关的东西必须使用真机 //在螺旋仪和加速计所有两种方式push和pull的方式,push的方式是时时 ...

  6. struts2防止重复提交的标签

    struts2 token 使用说明 --------------------------------------------------------------------------------- ...

  7. input、button、a标签 等定义的按钮尺寸的兼容性问题

    在项目中有遇到这类问题,搜索了一下解决方式,采用链接:https://segmentfault.com/q/1010000000190931 里各位楼主的答案,摘抄如下: 例子如下: HTML: &l ...

  8. 线索thread二叉树

    对于一个普通的二叉树 我们可以很明显的看到,在一个二叉树中,会有许多的空结点,而这些空结点必然会造成空间的浪费,为了解决这个问题,我们可以引入线索二叉树,把这些空结点利用起来,利用 '^' 记录给定结 ...

  9. 我使用的Bash脚本模板

    在Linux环境下(包括在相应的模拟环境,如Windows中的Cygwin)工作的时间久了,就会慢慢积累出一些自己写的小脚本程序,用于加速日常的操作与工作流程,如自动挂载与卸载U盘,映射网络驱动器,数 ...

  10. javascript动画效果之匀速运动

    html和css写在一起方便看,div通过定位设置为-200隐藏,span也是通过定位定在div靠左的中间 <!DOCTYPE html> <html> <head> ...