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了两次---@_@) ...
随机推荐
- 第14天dbutils与案例
第14天dbutils与案例 第14天dbutils与案例 1 1. 1.dbutils介绍 2 2. 2.dbutils快速入门 2 3. 3.dbutils A ...
- Partial Tree
Partial Tree 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5534 完全背包 做这题前去学习了下完全背包,觉得这个优化简直神技!(以前都是 ...
- shell初学
超简单的一段shell代码,查看电脑属性,删除无效安装包,查看天气.FYI #!/bin/bash echo -e '\n' echo "Hello,`whoami`" echo ...
- hdu_5286_wyh2000 and sequence(分块)
题目链接:hdu_5286_wyh2000 and sequence 题意: 给一段长度为N的序列,每次询问l-r(l和r和上一次询问的答案有关)内 不同的数的 出现次数的次方 的和.强制在线 题解: ...
- MySQL Replicationation进阶
摘要 上一篇: MySQL Replication 基础 下一篇 MySQL Replication-MHA 一.主主复制 二.半同步复制 三.复制过滤器 四.总结 五.切分 待续 一.主主复制 M ...
- 【转】ActiveMQ与虚拟通道
郑重提示,本文转载自http://shift-alt-ctrl.iteye.com/blog/2065436 ActiveMQ提供了虚拟通道的特性(Virtual Destination),它允许一个 ...
- HUST 1352 Repetitions of Substrings(字符串)
Repetitions of Substrings Description The “repetitions” of a string S(whose length is n) is a maximu ...
- 一步一步学EF系列2【最简单的一个实例】
整个文章我都会用最简单,最容易让人理解的方式给大家分享和共同学习.(由于live Writer不靠谱 又得补发一篇) 一.安装 Install-Package EntityFramework 二.简单 ...
- [ An Ac a Day ^_^ ] CodeForces 426C Sereja and Swaps 优先队列
题意: 给你一个有n个数的序列 取一个区间 这个区间内的数可以与区间外的值交换k次 问这样的区间最大值是多少 思路: 看数据是200 时间复杂度O(n*n) 应该可以暴力 顺便学习一下优先队列 枚举区 ...
- vultr使用snapshots系统镜像备份安装vps
vultr vps提供免费的snapshots功能,把你的vps做成镜像备份,在必要的时候可以恢复.如果你要配置多台机器,使用Snapshots非常方便好用. vultr添加snapshots很简单, ...