ZOJ - 1505 Solitaire 【双向BFS】
题目链接
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1505
题意
一个8 * 8 的棋盘上面有四个棋子
棋子可以上下左右移动,如果隔壁有个棋子 那就可以跳一步,只能跳一步。
给出 初始状态,和末尾状态 求能不能在8步之内达到
思路
如果是单向BFS (4 * 4)^ 8 = 2 ^ 32 个状态数
太大了
采用双向广搜
状态数 就是
(4 * 4)^ 4 * 2 = 2 ^ 17
因为内存只有32mb
然后我想 用八进制的数字 来存状态
然后转化成十进制
就是 8 ** 8 = 16777216
16777216 * 4 / 1024 = 65536kb = 64mb
爆内存了。。
然后后来想想,既然用了双向广搜来减少时间复杂度了,,不如直接用map 标记 也只是增加了log 的时间复杂度
就试试了。。
对了 那个状态 对四个棋子的位置 一定要排序后再转值 不然可能两个状态是一样的 但是得到的值确实不一样的
然后就A了。
AC代码
#pragma comment(linker, "/STACK:102400000,102400000")
#include <cstdio>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <set>
#include <list>
#include <numeric>
#include <sstream>
#include <iomanip>
#include <limits>
#define CLR(a, b) memset(a, (b), sizeof(a));
#define pb push_back
#define bug puts("***bug***");
#define fi first
#define se second
#define L(on) ((on)<<1)
#define R(on) (L(on) | 1)
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define syn_close ios::sync_with_stdio(false); cin.tie(0);
#define sp system("pause");
//#define gets gets_s
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <string, int> psi;
typedef pair <string, string> pss;
typedef pair <double, int> pdi;
const double PI = acos(-1.0);
const double EI = exp(1.0);
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3fll;
const int maxn = (int)4e3 + 10;
const int MAXN = (int)1e2 + 10;
const int MOD = (int)1e9 + 7;
int readint()
{
int num; scanf("%d", &num);
return num - 1;
}
struct node
{
pii G[4];
int step, value, vis;
bool operator == (const node& r)const
{
for (int i = 0; i < 8; i++)
if (r.G[i] != G[i])
return false;
return true;
}
void tran()
{
value = 0;
sort(G, G + 4, [](pii a, pii b) { if (a.fi == b.fi) return a.se < b.se; else return a.fi < b.fi; });
for (int i = 0; i < 4; i++) value = value * 10 + G[i].fi, value = value * 10 + G[i].se;
}
void read(int l, int r)
{
for (int i = l; i < r; i++) { G[i].fi = readint(); G[i].se = readint();}
step = 0; tran();
}
}st, tar;
void init()
{
st.G[0].se = readint(); st.G[0].fi--;
st.read(1, 4); tar.read(0, 4);
st.vis = 0; tar.vis = 1;
}
int Move[2][4][2] =
{
-1, 0,
1, 0,
0,-1,
0, 1,
-2, 0,
2, 0,
0,-2,
0, 2,
};
bool ok(int x, int y)
{
if (x < 0 || x >= 8 || y < 0 || y >= 8)
return false;
return true;
}
void bfs()
{
if (st == tar)
{
puts("YES");
return;
}
queue <node> q[2]; q[0].push(st); q[1].push(tar);
map <int, pii> mp[2]; mp[0][st.value] = pii(1, 0); mp[1][tar.value] = pii(1, 0);
while (!q[0].empty() && !q[1].empty())
{
node u;
if (q[0].size() < q[1].size()) { u = q[0].front(); q[0].pop(); }
else { u = q[1].front(); q[1].pop(); }
if (u.step >= 8) continue;
map <pii, int> visit;
for (int i = 0; i < 4; i++)
visit[u.G[i]] = 1;
for (int i = 0; i < 4; i++)
{
int x = u.G[i].fi, y = u.G[i].se;
for (int j = 0; j < 4; j++)
{
int nx = x + Move[0][j][0];
int ny = y + Move[0][j][1];
if (ok(nx, ny))
{
if (visit[pii(nx, ny)])
{
nx = x + Move[1][j][0];
ny = y + Move[1][j][1];
if (ok(nx, ny) && visit[pii(nx, ny)] == 0)
{
node v = u;
swap(v.G[i].fi, nx); swap(v.G[i].se, ny);
v.step++; v.tran();
if (mp[v.vis][v.value].fi == 0)
{
mp[v.vis][v.value] = pii(1, v.step);
pii tmp = mp[v.vis ^ 1][v.value];
if (tmp.fi == 1 && tmp.se + v.step <= 8)
{
puts("YES");
return;
}
q[v.vis].push(v);
}
}
}
else
{
node v = u;
swap(v.G[i].fi, nx); swap(v.G[i].se, ny);
v.step++; v.tran();
if (mp[v.vis][v.value].fi == 0)
{
mp[v.vis][v.value] = pii(1, v.step);
pii tmp = mp[v.vis ^ 1][v.value];
if (tmp.fi == 1 && tmp.se + v.step <= 8)
{
puts("YES");
return;
}
q[v.vis].push(v);
}
}
}
}
}
}
puts("NO");
return;
}
int main()
{
while (scanf("%d", &st.G[0].fi) != EOF)
{
init(); bfs();
}
}
ZOJ - 1505 Solitaire 【双向BFS】的更多相关文章
- Hdu1401-Solitaire(双向bfs)
Solitaire is a game played on a chessboard 8x8. The rows and columns of the chessboard are numbered ...
- HDU 1401 Solitaire 双向DFS
HDU 1401 Solitaire 双向DFS 题意 给定一个\(8*8\)的棋盘,棋盘上有4个棋子.每一步操作可以把任意一个棋子移动到它周围四个方向上的空格子上,或者可以跳过它四个方向上的棋子(就 ...
- POJ1915Knight Moves(单向BFS + 双向BFS)
题目链接 单向bfs就是水题 #include <iostream> #include <cstring> #include <cstdio> #include & ...
- HDU 3085 Nightmare II 双向bfs 难度:2
http://acm.hdu.edu.cn/showproblem.php?pid=3085 出的很好的双向bfs,卡时间,普通的bfs会超时 题意方面: 1. 可停留 2. ghost无视墙壁 3. ...
- POJ 3170 Knights of Ni (暴力,双向BFS)
题意:一个人要从2先走到4再走到3,计算最少路径. 析:其实这个题很水的,就是要注意,在没有到4之前是不能经过3的,一点要注意.其他的就比较简单了,就是一个双向BFS,先从2搜到4,再从3到搜到4, ...
- [转] 搜索之双向BFS
转自:http://www.cppblog.com/Yuan/archive/2011/02/23/140553.aspx 如果目标也已知的话,用双向BFS能很大程度上提高速度. 单向时,是 b^le ...
- 双向BFS
转自“Yuan” 如果目标也已知的话,用双向BFS能很大提高速度 单向时,是 b^len的扩展. 双向的话,2*b^(len/2) 快了很多,特别是分支因子b较大时 至于实现上,网上有些做法是用两个 ...
- HDU 3085 Nightmare Ⅱ (双向BFS)
Nightmare Ⅱ Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- HDU 3085 Nightmare Ⅱ 双向BFS
题意:很好理解,然后注意几点,男的可以一秒走三步,也就是三步以内的都可以,鬼可以穿墙,但是人不可以,鬼是一次走两步 分析:我刚开始男女,鬼BFS三遍,然后最后处理答案,严重超时,然后上网看题解,发现是 ...
随机推荐
- Business Process and SAP ERP
1. Definition of Organisation - Organizations are created entities within and through which people i ...
- Spring Boot(六): Favicon配置
1.默认的Favicon Spring Boot提供了一个默认的Favicon,每次访问应用的时候都能看到,如图所示. 2.关闭Favicon 我们可以在application.properties中 ...
- spark sql的简单操作
测试数据 sparkStu.text zhangxs chenxy wangYr teacher wangx teacher sparksql { ,"job":"che ...
- 在多点环境下使用cas实现单点登陆及登出
CAS 介绍 CAS 是 Yale 大学发起的一个开源项目,旨在为 Web 应用系统提供一种可靠的单点登录方法,CAS 在 2004 年 12 月正式成为 JA-SIG 的一个项目.CAS 具有以下特 ...
- GDB + gdbserver 远程调试mediaserver进程
远程调试步骤 在Android设备上启动gdbserver并attach你想调试的进程,并指定监听调试命令的端口(此端口是TV上的端口) $ adb shell # ps |grep media # ...
- 关于reset.css的那些事
分析过程:body: 发现在没有填写任何内容的情况下是没有margin 的 只有在加入了文字或者div中以后才有了margin(废话)那么 我想问一下 body的padding 默认的有吗??在哪里 ...
- C语言基础知识【数组】
2017年7月11日17:34:05C 数组1.C 语言支持数组数据结构,它可以存储一个固定大小的相同类型元素的顺序集合.数组是用来存储一系列数据,但它往往被认为是一系列相同类型的变量.数组的声明并不 ...
- 【bzoj2226】[Spoj 5971] LCMSum 欧拉函数
题目描述 Given n, calculate the sum LCM(1,n) + LCM(2,n) + .. + LCM(n,n), where LCM(i,n) denotes the Leas ...
- City Game(最大子矩阵)
Bob is a strategy game programming specialist. In his new city building game the gaming environment ...
- java ScriptEngine 使用
Java SE 6最引人注目的新功能之一就是内嵌了脚本支持.在默认情况下,Java SE 6只支持JavaScript,但这并不以为着Java SE 6只能支持JavaScript.在Java SE ...