POJ 1198/HDU 1401
双向广搜。。。
呃,双向广搜一般都都用了HASH判重,这样可以更快判断两个方向是否重叠了。这道题用了双向的BFS,有效地减少了状态。但代码太长了,不写,贴一个别人的代码。。
#include<iostream>
#include<set>
#include<queue>
#include<algorithm>
using namespace std; typedef __int64 i64; const i64 one = (i64);
const int maxn = << ;
int dx[] = { , ,- , } ;
int dy[] = { , , , - }; struct node
{
i64 bd;
int pos[];
}; node st , ed ; i64 stq[maxn] ,edq[maxn] , sz ,ez ; set<i64> win ;
set<i64>:: iterator it ; bool IsOut( int cx,int cy)
{
return cx < || cy < || cx >= || cy >= ;
} bool IsOn( i64 bd ,int cx, int cy)
{
return bd & ( one<<(cx * + cy) ) ;
} void clr( i64 &bd ,int i)
{
if( ! IsOn( bd , i/ , i%) ) return ;
bd -= one<<i;
} void put( i64 &bd, int i )
{
if(IsOn(bd ,i/ ,i%) ) return ;
bd += one <<i ;
} bool next(node cur, int i,int j , node &son)
{
int t , tx , ty , nx , ny , cx , cy ;
i64 bd = cur.bd;
t = cur.pos[i] , tx = t / , ty = t % ;
nx = tx + dx[j] , ny = ty + dy[j] ;
if( IsOut(nx, ny) ) return false;
if( IsOn (bd , nx, ny) )
{
cx = *nx - tx, cy = *ny - ty;
if( IsOut(cx , cy) || IsOn(bd , cx , cy) ) return false;
clr(cur.bd, tx* + ty);
put(cur.bd, cx* + cy);
cur.pos[i] = cx * + cy;
son = cur;
return true;
}
clr(cur.bd , tx * + ty); put(cur.bd , nx * + ny);
cur.pos[i] = nx * + ny ;
son = cur;
return true;
} void deal(node bgn )
{
int i , j , dep = ;
node cur , son , tail;
queue<node> q; tail.bd = - ;
win.clear(); win.insert(bgn.bd);
q.push(tail); q.push(bgn);
while(!q.empty())
{
cur = q.front(); q.pop();
if( cur.bd == - )
{
if(q.empty()) return ;
q.push(tail); cur = q.front() ; q.pop();
if( ++ dep > ) return ;
}
for(i = ; i < ;++i)
for( j = ;j < ;++j )
if ( next( cur , i , j , son ) )
if( win.find(son.bd) ==win.end() )
{
q.push(son);
win.insert(son.bd);
}
}
} int bbs(i64 x)
{
int l , r ,mid;
l = , r = ez - ;
while(l <= r)
{
mid = ( l + r) / ;
if(edq[ mid ] == x) return mid ;
else if ( x < edq[mid] ) r = mid - ;
else l = mid + ;
}
return -;
} bool can()
{
int i , x[],y[] ,check ;
if(scanf("%d%d%d%d%d%d%d%d",&x[],&y[],&x[],&y[],&x[],&y[],&x[],&y[]) == EOF )
return false;
st.bd = ;
for(i = ; i< ; ++i)
{
-- x[i] , -- y[i] ;
put(st.bd , x[i] * + y[i]);
st.pos[i] = x[i] * + y[i];
} ed.bd = ;
for(i = ; i< ; ++i)
{
scanf("%d%d",&x[i],&y[i]);
-- x[i] , -- y[i];
put(ed.bd , x[i] * + y[i]);
ed.pos[i] = x[i] * + y[i] ;
} sz = ez = ; deal(st);
for(it = win.begin() ; it!=win.end(); it ++ )
stq[sz ++ ] = *it; deal(ed);
for(it = win.begin() ; it!=win.end(); it++)
edq[ez ++ ] = *it ; sort(edq , edq + ez); check = ;
for(i = ; i < sz && !check ; ++i)
if( bbs(stq[i]) !=- )
check = ; if(check)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
return true;
} int main()
{
while(can());
return ;
}
POJ 1198/HDU 1401的更多相关文章
- poj 1198 hdu 1401 搜索+剪枝 Solitaire
写到一半才发现能够用双向搜索4层来写,但已经不愿意改了,干脆暴搜+剪枝水过去算了. 想到一个非常水的剪枝,h函数为 当前点到终点4个点的最短距离加起来除以2.由于最多一步走2格,然后在HDU上T了, ...
- POJ 1198 / HDU 1401 Solitaire (记忆化搜索+meet in middle)
题目大意:给你一个8*8的棋盘,上面有四个棋子,给你一个初始排布,一个目标排布,每次移动,可以把一个棋子移动到一个相邻的空位,或者跨过1个相邻的棋子,在保证棋子移动不超过8次的情况下,问能否把棋盘上的 ...
- POJ 2104&HDU 2665 Kth number(主席树入门+离散化)
K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 50247 Accepted: 17101 Ca ...
- poj 1251 poj 1258 hdu 1863 poj 1287 poj 2421 hdu 1233 最小生成树模板题
poj 1251 && hdu 1301 Sample Input 9 //n 结点数A 2 B 12 I 25B 3 C 10 H 40 I 8C 2 D 18 G 55D 1 E ...
- Eight POJ - 1077 HDU - 1043 八数码
Eight POJ - 1077 HDU - 1043 八数码问题.用hash(康托展开)判重 bfs(TLE) #include<cstdio> #include<iostream ...
- HDU 1401 Solitaire 双向DFS
HDU 1401 Solitaire 双向DFS 题意 给定一个\(8*8\)的棋盘,棋盘上有4个棋子.每一步操作可以把任意一个棋子移动到它周围四个方向上的空格子上,或者可以跳过它四个方向上的棋子(就 ...
- POJ 1177/HDU 1828 picture 线段树+离散化+扫描线 轮廓周长计算
求n个图矩形放下来,有的重合有些重合一部分有些没重合,求最后总的不规则图型的轮廓长度. 我的做法是对x进行一遍扫描线,再对y做一遍同样的扫描线,相加即可.因为最后的轮廓必定是由不重合的线段长度组成的, ...
- POJ 1308&&HDU 1272 并查集判断图
HDU 1272 I - 小希的迷宫 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64 ...
- POJ 1077 && HDU 1043 Eight A*算法,bfs,康托展开,hash 难度:3
http://poj.org/problem?id=1077 http://acm.hdu.edu.cn/showproblem.php?pid=1043 X=a[n]*(n-1)!+a[n-1]*( ...
随机推荐
- 95.Extjs 表单中自定义的验证规则 VTypes
1 Ext.onReady(function(){ Ext.QuickTips.init(); //重写 (自定义)xtype Ext.apply(Ext.form.VTypes,{ repetiti ...
- Coursera Algorithms week2 基础排序 练习测验: Intersection of two sets
题目原文: Given two arrays a[] and b[], each containing n distinct 2D points in the plane, design a subq ...
- Coursera Algorithms week1 查并集 练习测验:3 Successor with delete
题目原文: Given a set of n integers S = {0,1,…,N-1}and a sequence of requests of the following form: Rem ...
- [JavaEE] JBoss主要版本下载链接一览
URL: http://teddysun.com/260.html JBoss在2006年被 RedHat 收购.在各种 J2EE 应用服务器中,JBoss 是最受欢迎而且功能最为强大的应用服务器.不 ...
- sdut1269 走迷宫(dfs)
http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=1269 连着做了三个基本的dfs,终于弄懂了搜索 ...
- 2205 等差数列(dp)
2205 等差数列 时间限制: 1 s 空间限制: 32000 KB 题目等级 : 钻石 Diamond 题目描述 Description 等差数列的定义是一个数列S,它满足了(S[i] ...
- linux shell 编程笔记
重定向和管道 输出重定向:把在终端输出的内容保存到文件上 输入重定向:通过文件的格式输入内容到终端 管道:把上一条命令的输出作为下一条命令的输入,如同管道一样,所有命令同时进行,同时处理数据,不 ...
- 前端-Vue结构思维导图笔记
看不清的朋友右键保存或者新窗口打开哦!喜欢我可以关注我,还有更多前端思维导图笔记有vue结构分析,JS基础,JQ,JS高级,Angular,git等等
- 使用DOM解析XML文档
简单介绍一下使用DOM解析XML文档,解析XML文件案例: <?xml version="1.0" encoding="UTF-8"?> -< ...
- dubbo之集群容错
在集群调用失败时,Dubbo 提供了多种容错方案,缺省为 failover 重试. 集群容错模式 1. Failover Cluster 失败自动切换,当出现失败,重试其它服务器 .通常用于读操作,但 ...