hdu 3004 The Chess【广独优先搜索】

The Chess

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 466    Accepted Submission(s): 130

Problem Description

Mr Li likes playing chess very much. One day he made a simplified version of the game. The chess board is relatively smaller. He will first place only three kinds of chesses on his own behalf, namely the Chariot("ju"), the Horse("ma")
and the Cannon("pao"). Then he placed some chesses on the opposite‘s behalf. There will be one and only one chess of the opposite marked as the General("shuai"). Mr Li wants to kill the General as soon as possible without killing other chesses.

All chesses will move in the same way as in real chess games(The chinese chess).

To make the game easier, the opposite‘s chesses will stand still.

Input

For each test case,the first line contains two integers n and m(2<=n,m<=10) indicating the size of the borad. The next n lines, containing m characters each, describe the board. ‘C‘, ‘M‘ and ‘P‘ stand for the Chariot, the Horse and
the Cannon on Mr Li‘s behalf. ‘S‘ stands for the General of the opposite while ‘D‘ stands for other chesses. Cells marked as ‘.‘ are empty.

Process to the end of file.

Output

For each test case, first print a line saying "Scenario #k", where k is the number of the test case.Then,if Mr Li can kill the General, print the least number of steps needed. Otherwise print the sentence "OH!That‘s impossible!".Print
a blank line after each test case, even after the last one.

Sample Input

5 5
..DSD
...D.
C....
P.D..
...M.
7 7
.DDSDD.
..DDD..
...D...
.....P.
.C.....
...M...
.......

Sample Output

Scenario #1
2

Scenario #2
OH!That‘s impossible!

分析:这是一个很好的搜索问题,不知为什么用cin就wa,换成%s就ac了,坑了一天,坑急眼了连饭都没吃。

广搜就是遍历车,马,炮所有的位置状态,开一个6维数组标记3个元素的位置,车,马比较好遍历,车4个方向,马8个·方向,炮除了可以和车一样走外

还可以,还可以“隔山打牛”。注意:马可以被拨马腿,炮不能走到帅的位置上。

代码示例:

#include<stdio.h>

#include<string.h>

#include<algorithm>

#include<iostream>

#include<queue>

using namespace std;

typedef struct

{

int xj,xm,xp;

int yj,ym,yp;

int step;

}node;

int map[11][11],dis[11][11][11][11][11][11];

int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};

int dit[8][2]={{2,1},{1,2},{-2,1},{1,-2},{2,-1},{-1,2},{-2,-1},{-1,-2}};

int dic[8][2]={{1,0},{0,1},{-1,0},{0,-1},{1,0},{0,1},{-1,0},{0,-1}};

int N,M,ax,ay,bx,by,cx,cy,X,Y;

int min(int a,int b)

{

return a<b?a:b;

}

int max(int a,int b)

{

return a>b?a:b;

}

int bfs()

{

int num,h,t;

node fir,nex;

fir.xj=ax,fir.xm=bx,fir.xp=cx;

fir.yj=ay,fir.ym=by,fir.yp=cy;

fir.step=0;

dis[ax][ay][bx][by][cx][cy]=1;

queue<node>Q;

Q.push(fir);

while(!Q.empty())

{

fir=Q.front();

Q.pop();

map[fir.xj][fir.yj]=1;

map[fir.xm][fir.ym]=1;

map[fir.xp][fir.yp]=1;

for(int i=0;i<8;i++)

{

nex=fir;

nex.xm=fir.xm+dit[i][0];

nex.ym=fir.ym+dit[i][1];

nex.step=fir.step+1;

if((fir.xm+dic[i][0]==X)&&(fir.ym+dic[i][1]==Y))continue;

if(map[fir.xm+dic[i][0]][fir.ym+dic[i][1]])continue;

if(nex.xm>=1&&nex.xm<=N&&nex.ym>=1&&nex.ym<=M&&!map[nex.xm][nex.ym]&&!dis[nex.xj][nex.yj][nex.xm][nex.ym][nex.xp][nex.yp])

{

if(nex.xm==X&&nex.ym==Y)

{

return nex.step;

}

dis[nex.xj][nex.yj][nex.xm][nex.ym][nex.xp][nex.yp]=1;

Q.push(nex);

}

}

for(int i=0;i<4;i++)

{

nex=fir;

nex.xj=fir.xj+dir[i][0];

nex.yj=fir.yj+dir[i][1];

nex.step=fir.step+1;

while(1)

{

if(nex.xj>=1&&nex.xj<=N&&nex.yj>=1&&nex.yj<=M&&!map[nex.xj][nex.yj]&&!dis[nex.xj][nex.yj][nex.xm][nex.ym][nex.xp][nex.yp])

{

if(nex.xj==X&&nex.yj==Y)

{

return nex.step;

}

dis[nex.xj][nex.yj][nex.xm][nex.ym][nex.xp][nex.yp]=1;

Q.push(nex);

}

else

{

break;

}

nex.xj+=dir[i][0];

nex.yj+=dir[i][1];

}

}

for(int i=0;i<4;i++)

{

nex=fir;

nex.xp=fir.xp+dir[i][0];

nex.yp=fir.yp+dir[i][1];

nex.step=fir.step+1;

num=0;

while(1)

{

if(!(nex.xp>=1&&nex.xp<=N&&nex.yp>=1&&nex.yp<=M))break;

if(map[nex.xp][nex.yp])num++;

if(num>1)break;

if(nex.xp==X&&nex.yp==Y&&num==0)

break;

if(nex.xp==X&&nex.yp==Y&&num==1)

{

// printf("<%d,%d>\n",nex.xp,nex.yp);

return nex.step;

}

if(!map[nex.xp][nex.yp]&&!dis[nex.xj][nex.yj][nex.xm][nex.ym][nex.xp][nex.yp]&&num==0)

{

dis[nex.xj][nex.yj][nex.xm][nex.ym][nex.xp][nex.yp]=1;

Q.push(nex);

}

nex.xp+=dir[i][0];

nex.yp+=dir[i][1];

}

}

map[fir.xj][fir.yj]=0;

map[fir.xm][fir.ym]=0;

map[fir.xp][fir.yp]=0;

}

return -1;

}

int main()

{

char c[21][21];

int l=0;

while(~scanf("%d%d",&N,&M))

{

memset(dis,0,sizeof(dis));

for(int i=1;i<=N;i++)

scanf("%s",c[i]+1);

for(int i=1;i<=N;i++)

for(int j=1;j<=M;j++)

{

//cin>>c;

if(c[i][j]==‘D‘)

{

map[i][j]=1;

}

else

{

map[i][j]=0;

}

if(c[i][j]==‘S‘)

{

X=i,Y=j;

continue;

}

if(c[i][j]==‘C‘)

{

ax=i,ay=j;

continue;

}

if(c[i][j]==‘M‘)

{

bx=i,by=j;

continue;

}

if(c[i][j]==‘P‘)

{

cx=i,cy=j;

}

}

int time=bfs();

l++;

printf("Scenario #%d\n",l);

if(time==-1)

{

printf("OH!That‘s impossible!\n\n");

}

else

printf("%d\n\n",time);

}

return 0;

}

时间: 2024-12-26 16:44:43

hdu 3004 The Chess【广独优先搜索】的相关文章

关于广/宽度优先搜索

嗯... BFS是图的搜索算法之一,与深度优先搜索不同的是:广度优先搜索会先搜索到与起始点距离较近的点,而深搜却是沿着一个分支递归到最后.... 与深搜的对比: 深搜用栈(stack)来实现: 1.把起始顶点压入栈中 2.每次从栈顶取出一个顶点,搜索所有它的未访问相邻顶点,把这些顶点压入栈中 3.重复执行第二步操作,直到找到所要找的站的顶点货着栈为空时结束程序 广搜用队列(queue)来实现: 1.把起始顶点放到队列中 2.每次从队首取出一个顶点,查看这个顶点所有的未访问相邻顶点,把它们那放到队

hdu 3345 War Chess (bfs+优先队列)

War Chess Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1732    Accepted Submission(s): 416 Problem Description War chess is hh's favorite game: In this game, there is an N * M battle map, an

层层递进——宽度优先搜索(BFS)

问题引入 我们接着上次“解救小哈”的问题继续探索,不过这次是用宽度优先搜索(BFS). 注:问题来源可以点击这里 http://www.cnblogs.com/OctoptusLian/p/7429645.html 最开始小哼在入口(1,1)处,一步之内可以到达的点有(1,2)和(2,1). 但是小哈并不在这两个点上,那小哼只能通过(1,2)和(2,1)这两点继续往下走. 比如现在小哼走到了(1,2)这个点,之后他又能够到达哪些新的点呢?有(2,2).再看看通过(2,1)又可以到达哪些点呢?可以

广度/宽度优先搜索(BFS)详解

广度/宽度优先搜索(BFS) [算法入门] 1.前言 广度优先搜索(也称宽度优先搜索,缩写BFS,以下采用广度来描述)是连通图的一种遍历策略.因为它的思想是从一个顶点V0开始,辐射状地优先遍历其周围较广的区域,故得名. 一般可以用它做什么呢?一个 广度/宽度优先搜索(BFS) 算法导论里边会给出不少严格的证明,我想尽量写得通俗一点,因此采用一些直观的讲法来伪装成证明,关键的point能够帮你get到就好. 2.图的概念 刚刚说的广度优先搜索是连通图的一种遍历策略,那就有必要将图先简单解释一下.

宽度优先搜索(BFS)

宽度优先搜索,又称为广度优先搜索,简称BFS 搜索过程:从初始结点开始,逐层向下扩展,即第n层搜索未完成,不得进入下一层搜索 一.初始结点入队,进入循环 二.取出队列的第一个元素 三.判断该结点是不是目标结点,如果是目标结点,则问题解决,跳出循环 四.如果该结点不是目标结点,判断其是否能够扩展,若不能,跳到步骤二 五.如果该结点能扩展,将其子结点放入队列的尾部 六.跳到步骤二 用一个经典的例子(走迷宫)来感受下 给定一个二维数组 int a[10][10] = {0 , 1 , 0 , 0 ,

HDU 1253 (简单三维广搜) 胜利大逃亡

奇葩!这么简单的广搜居然爆内存了,而且一直爆,一直爆,Orz 而且我也优化过了的啊,尼玛还是一直爆! 先把代码贴上睡觉去了,明天再来弄 1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <queue> 6 #include <cmath> 7 using namespace std; 8 9 struct Poin

HDU 4405 Aeroplane chess (概率DP求期望)

题意:有一个n个点的飞行棋,问从0点掷骰子(1~6)走到n点需要步数的期望 其中有m个跳跃a,b表示走到a点可以直接跳到b点. dp[ i ]表示从i点走到n点的期望,在正常情况下i点可以到走到i+1,i+2,i+3,i+4,i+5,i+6 点且每个点的概率都为1/6 所以dp[i]=(dp[i+1]+dp[i+2]+dp[i+3]+dp[i+4]+dp[i+5]+dp[i+6])/6  + 1(步数加一). 而对于有跳跃的点直接为dp[a]=dp[b]; #include<stdio.h>

HDU 4597 Play Game (记忆化搜索)

题意:有两堆n张的卡片,每张卡片有一个得分,Alice和Bob轮流在两堆卡片的两端取卡片 问Alice先手,取得分数最多为多少: #include <stdio.h> #include <iostream> #include <algorithm> #include <string.h> #include <queue> #include <math.h> #define M 50 #define LL long long using

hdu 1501 Zipper (dfs+记忆化搜索)

Zipper Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6491    Accepted Submission(s): 2341 Problem Description Given three strings, you are to determine whether the third string can be formed