Solitaire

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4122    Accepted Submission(s): 1245

Problem Description
Solitaire
is a game played on a chessboard 8x8. The rows and columns of the
chessboard are numbered from 1 to 8, from the top to the bottom and from
left to right respectively.

There are four identical pieces on the board. In one move it is allowed to:

> move a piece to an empty neighboring field (up, down, left or right),

> jump over one neighboring piece to an empty field (up, down, left or right).

There
are 4 moves allowed for each piece in the configuration shown above. As
an example let's consider a piece placed in the row 4, column 4. It can
be moved one row up, two rows down, one column left or two columns
right.

Write a program that:

> reads two chessboard configurations from the standard input,

> verifies whether the second one is reachable from the first one in at most 8 moves,

> writes the result to the standard output.

 
Input
Each
of two input lines contains 8 integers a1, a2, ..., a8 separated by
single spaces and describes one configuration of pieces on the
chessboard. Integers a2j-1 and a2j (1 <= j <= 4) describe the
position of one piece - the row number and the column number
respectively. Process to the end of file.
 
Output
The
output should contain one word for each test case - YES if a
configuration described in the second input line is reachable from the
configuration described in the first input line in at most 8 moves, or
one word NO otherwise.
 
Sample Input
4 4 4 5 5 4 6 5
2 4 3 3 3 6 4 6
 
Sample Output
YES
 
题意:给定4个点的初始状态,点每次移动可以有两种方式。一种是如果相邻点是空的,移动到相邻点,如果相邻点非空,并且相邻点同一个方向没有点,则可以跳过去到下一个点,问8步以内能否移动到目标状态??
题解:4个点可以想到用8维数组保存状态,,但是一定要压缩压缩再压缩,强剪枝。。自己代码剪枝没通过,参考的大神的,,不过双向BFS好像快些。。而且只能用G++交才能AC。
#include<stdio.h>
#include<queue>
#include<iostream>
#include <string.h>
#include <algorithm>
#include <map>
using namespace std;
typedef long long LL;
struct Node{
int x[],y[];
int step;
}s,t;
int graph[][];
bool vis[][][][][][][][];
bool equals(Node a){ ///这个地方开始想错了,以为是每一个点的状态对应下一行每一行的状态,结果是只要能到达目标
///状态就OK,比如说是起始地第二个点到达目标的第一个点
for(int i=;i<;i++){
if(!graph[a.x[i]][a.y[i]]) return false;
}
return true;
}
bool check(Node a){
for(int i=;i<;i++){
if(a.x[i]<||a.x[i]>=||a.y[i]<||a.y[i]>=) return false;
}
if(vis[a.x[]][a.y[]][a.x[]][a.y[]][a.x[]][a.y[]][a.x[]][a.y[]]) return false;
return true;
}
bool cango(Node next,int k){
for(int i=;i<;i++){
if(i!=k&&next.x[i]==next.x[k]&&next.y[i]==next.y[k]) return false;
}
return true;
}
int dir[][] = {{,},{-,},{,},{,-}}; bool bfs(){
queue<Node> q;
q.push(s);
s.step = ;
while(!q.empty()){
Node now = q.front();
q.pop();
if(now.step>){
return false;
}
if(equals(now)){
return true;
}
for(int i=;i<;i++){
for(int j=;j<;j++){
Node next = now;
next.x[i] = now.x[i]+dir[j][];
next.y[i] = now.y[i]+dir[j][];
next.step = now.step+;
if(next.step>) continue; ///大神的剪枝是>=8
if(!check(next)) continue;
if(cango(next,i)){
if(equals(next)) return true;
vis[next.x[]][next.y[]][next.x[]][next.y[]][next.x[]][next.y[]][next.x[]][next.y[]] = true;
q.push(next);
}
else{
next.x[i] = now.x[i]+*dir[j][];
next.y[i] = now.y[i]+*dir[j][];
if(!check(next)) continue;
if(cango(next,i)){
if(equals(next)) return true;
vis[next.x[]][next.y[]][next.x[]][next.y[]][next.x[]][next.y[]][next.x[]][next.y[]] = true;
q.push(next);
}
}
}
}
}
return false;
}
int main()
{
while(scanf("%d%d",&s.x[],&s.y[])!=EOF){
memset(graph,,sizeof(graph));
s.x[]-=,s.y[]-=;
for(int i=;i<;i++){
scanf("%d%d",&s.x[i],&s.y[i]);
s.x[i]--;
s.y[i]--;
}
for(int i=;i<;i++){
scanf("%d%d",&t.x[i],&t.y[i]);
t.x[i]--;
t.y[i]--;
graph[t.x[i]][t.y[i]] = ;
}
memset(vis,false,sizeof(vis));
vis[s.x[]][s.y[]][s.x[]][s.y[]][s.x[]][s.y[]][s.x[]][s.y[]] = true;
bool flag = bfs();
if(flag) printf("YES\n");
else printf("NO\n");
}
return ;
}

双广的话非常快,主要是怎么处理初始状态和目标状态,因为有可能第1个最后跳到二状态去了,这里的解决办法是排个序之后就解决了。

#include<stdio.h>
#include<queue>
#include<iostream>
#include <string.h>
#include <algorithm>
#include <map>
using namespace std;
typedef long long LL;
struct Point{
int x,y;
};
struct Node{
Point p[];
int step;
}s,t;
char vis[][][][][][][][];
int graph[][];
int cmp(Point a,Point b){
if(a.x==b.x) return a.y<b.y;
return a.x<b.x;
}
void make_vis(Node s,char c){
vis[s.p[].x][s.p[].y][s.p[].x][s.p[].y][s.p[].x][s.p[].y][s.p[].x][s.p[].y] = c;
}
char checkvis(Node s){
return vis[s.p[].x][s.p[].y][s.p[].x][s.p[].y][s.p[].x][s.p[].y][s.p[].x][s.p[].y];
}
void make_graph(Node s){
memset(graph,,sizeof(graph));
for(int i=;i<;i++){
graph[s.p[i].x][s.p[i].y] = ;
}
}
bool check(Node s){
for(int i=;i<;i++){
if(s.p[i].x<||s.p[i].x>=) return false;
if(s.p[i].y<||s.p[i].y>=) return false;
}
return true;
}
int dir[][]={{,},{-,},{,},{,-}};
bool bfs(){
memset(vis,,sizeof(vis));
make_vis(s,'');
make_vis(t,'');
queue<Node> q1,q2;
q1.push(s);
q2.push(t);
while(!q1.empty()||!q2.empty()){
if(!q1.empty()){
Node now = q1.front();
q1.pop();
if(now.step>=) continue;
make_graph(now);
for(int i=;i<;i++){
for(int j=;j<;j++){
Node next = now;
next.p[i].x += dir[j][];
next.p[i].y += dir[j][];
next.step++;
if(!check(next)) continue;
if(graph[next.p[i].x][next.p[i].y]){
next.p[i].x += dir[j][];
next.p[i].y += dir[j][];
if(!check(next)||graph[next.p[i].x][next.p[i].y]) continue;
}
sort(next.p,next.p+,cmp);
if(checkvis(next)=='') continue;
else if(checkvis(next)=='') return true;
make_vis(next,'');
q1.push(next);
}
}
}
if(!q2.empty()){
Node now = q2.front();
q2.pop();
if(now.step>=) continue;
make_graph(now);
for(int i=;i<;i++){
for(int j=;j<;j++){
Node next = now;
next.p[i].x += dir[j][];
next.p[i].y += dir[j][];
next.step++;
if(!check(next)) continue;
if(graph[next.p[i].x][next.p[i].y]){
next.p[i].x += dir[j][];
next.p[i].y += dir[j][];
if(!check(next)||graph[next.p[i].x][next.p[i].y]) continue;
}
sort(next.p,next.p+,cmp);
if(checkvis(next)=='') continue;
else if(checkvis(next)=='') return true;
make_vis(next,'');
q2.push(next);
}
}
}
}
return false;
}
int main()
{
while(scanf("%d%d",&s.p[].x,&s.p[].y)!=EOF){
memset(graph,,sizeof(graph));
s.p[].x-=,s.p[].y-=;
for(int i=;i<;i++){
scanf("%d%d",&s.p[i].x,&s.p[i].y);
s.p[i].x--;
s.p[i].y--;
}
for(int i=;i<;i++){
scanf("%d%d",&t.p[i].x,&t.p[i].y);
t.p[i].x--;
t.p[i].y--;
}
s.step = t.step = ;
sort(s.p,s.p+,cmp);
sort(t.p,t.p+,cmp);
bool flag = bfs();
if(flag) printf("YES\n");
else printf("NO\n");
}
return ;
}

hdu 1401(单广各种卡的搜索题||双广秒速)的更多相关文章

  1. POJ 1198 / HDU 1401 Solitaire (记忆化搜索+meet in middle)

    题目大意:给你一个8*8的棋盘,上面有四个棋子,给你一个初始排布,一个目标排布,每次移动,可以把一个棋子移动到一个相邻的空位,或者跨过1个相邻的棋子,在保证棋子移动不超过8次的情况下,问能否把棋盘上的 ...

  2. HDU 1401 Solitaire 双向DFS

    HDU 1401 Solitaire 双向DFS 题意 给定一个\(8*8\)的棋盘,棋盘上有4个棋子.每一步操作可以把任意一个棋子移动到它周围四个方向上的空格子上,或者可以跳过它四个方向上的棋子(就 ...

  3. hdu 4778 Gems Fight! 博弈+状态dp+搜索

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4102743.html 题目链接:hdu 4778 Gems Fight! 博弈+状态dp+搜 ...

  4. [HDU 2102] A计划(搜索题,典型dfs or bfs)

    A计划 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  5. HDU 1403 Eight&POJ 1077(康拖,A* ,BFS,双广)

    Eight Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  6. HDU 3131 One…Two…Five! (暴力搜索)

    题目链接:pid=3131">HDU 3131 One-Two-Five! (暴力搜索) 题意:给出一串数字,要求用加,减,乘,除(5/2=2)连接(计算无优先级:5+3*6=8*6= ...

  7. hdu.1043.Eight (打表 || 双广 + 奇偶逆序)

    Eight Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  8. poj 1416 (hdu 1539)Shredding Company:剪枝搜索

    点击打开链接 题目大意是有一个分割机,可以把一串数字分割成若干个数字之后求和,题目输入一个数字上界和待分割的数字,让我们求出分割后数字之和在不超过给定max的情况下的最大值,并且给出分割方案,如果没有 ...

  9. 历年NOIP中的搜索题

    什么题目都不会做于是开始做搜索题. 然而我搜索题也不会做了. 铁定没戏的蒟蒻. 1.NOIP2004 虫食算 “对于给定的N进制加法算式,求出N个不同的字母分别代表的数字,使得该加法算式成立.输入数据 ...

随机推荐

  1. 【点分治】luoguP2664 树上游戏

    应该是一道中等难度的点分?麻烦在一些细节. 题目描述 lrb有一棵树,树的每个节点有个颜色.给一个长度为n的颜色序列,定义s(i,j) 为i 到j 的颜色数量.以及 现在他想让你求出所有的sum[i] ...

  2. destoon 自定义session丢失

    destoon 在使用session之前 应该实例化 $s​ession = new dsession(); destoon通过配置文件加载了不同session存储方式.如果你使用session的页面 ...

  3. 【windows】共享文件夹设置

    控制面板\网络和 Internet\网络和共享中心\高级共享设置 在当前的域\公用\家庭网络 下文件和打印机共享开关打开 现在可以在 计算机-网络 里面看到共享的计算机啦 选中自己想要分享的文件,右键 ...

  4. python中打印金字塔和九九乘法表的几种方法

    # 打印九九乘法表for i in range(1,10): for j in range(1,i+1): # x=i*j # print(i,'*',j,'=',x,end=' ') print(' ...

  5. leetcode-13-basic-binaryTree

    101. Symmetric Tree 解题思路: 递归的方法如下.分几种情况考虑,如果左子树和右子树都是空,那么返回true:如果不同时为空,返回false:如果都不为空,则 判断其值是否相等,不相 ...

  6. python中子进程不支持input()函数输入

    错误的源代码: import socketimport threadingimport multiprocessing# 创建socketserve_socket = socket.socket(so ...

  7. Java-创建一个线程

    第一种继承Thread类 package com.tj; public class BasicThread1 extends Thread { public void run() { System.o ...

  8. Mime类型与文件后缀对照表及探测文件MIME的方法

    说明:刚刚写了一篇<IHttpHandler的妙用(2):防盗链!我的资源只有我的用户才能下载>的文章,网址:http://blog.csdn.net/zhoufoxcn/archive/ ...

  9. day04_09 while循环03

    练习题: 3.如何输入一个如下的直角三角形,用户指定输出行数:(如果上下反转,右如何实现?) ********** 以下是自己的思路,没有按照上课老师的思路,反正经过不断的测试改进得出的算法 num ...

  10. bat 中的特殊符号输出问题

    系统关键字(感叹号!)冲突 由于是自动化部署,因此需要使用到循环,这里就不可避免的用到了延迟变量(setlocal enabledelayedexpansion) 有关延迟变量的知识,大家可以通过这篇 ...