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]*( ...
随机推荐
- B4321 queue2 dp
这个题的dp真的恶心.首先,一开始我以为是一道数论题,但是组合数和这个题没啥关系.dp方程巨麻烦,状态是dp[i][j][0/1],代表i位连了j个,上一位是否连着.然后开始转移,证明如下: 我们先来 ...
- spring 监听器 IntrospectorCleanupListener简介
转自:https://blog.csdn.net/ywb201314/article/details/51144256 其中JavaBeans Introspector是一个类,位置在Java.bea ...
- 99.ext afteredit事件详解
转自:http://www.jcodecraeer.com/a/jquery_js_ajaxjishu/2012/0524/203.html 1 摘要 grid.on(afteredit,afterE ...
- bzoj 2599(点分治)
2599: [IOI2011]Race Time Limit: 70 Sec Memory Limit: 128 MBSubmit: 3642 Solved: 1081[Submit][Statu ...
- EF6 自定义迁移表名
在下列代码片段中已经EF6迁移表的表名更改为 MigrationHistory注意:下代码片段建议和DbContext同程序集 public class ModelConfiguration : Db ...
- BZOJ 3679 数位DP
思路: f[i][j]表示i位数乘积为j的方案数 j的取值最多5000多种,那就开个map存一下好了 f[i][mp[k*rec[j]]]+=f[i-1][j]; //By SiriusRen #in ...
- 【转】js中几种实用的跨域方法原理详解
这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...
- 设计模式之合成模式(Java语言描述)
<JAVA与模式>一书中开头是这样描述合成(Composite)模式的: 合成模式属于对象的结构模式,有时又叫做"部分--整体"模式.合成模式将对象组织到树结构中,可以 ...
- spring - quartz - experssion 表达式
字段 允许值 允许的特殊字符 秒 0-59 , - * / 分 0-59 , - * / 小时 0-23 , - * / 日期 1-31 , - * ? / L W C 月份 1-12 或者 JAN- ...
- 【Oracle】数据迁移工具(1):SQL Loader
SQL Loader是一种数据加载工具,可以把外部数据加载到Oracle数据库中.SQL Loader中的参数有很多,本文只在第一部分中列出常用参数.要想运用SQL Loader工具 ,需要我们编辑一 ...