过河卒(BFS)

Posted Mr.wu123

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了过河卒(BFS)相关的知识,希望对你有一定的参考价值。

过河卒
Time Limit: 5000 MS Memory Limit: 65536 K
Total Submit: 296(91 users) Total Accepted: 73(56 users) Rating: Special Judge: No
Description
Lda学会了中国象棋,在一次与Kevin的切磋中,Lda不幸只剩下一只过河卒了,而Kevin还有很多棋子。

过河卒在棋盘上能移动的范围是一个5×9的平面(如图)。据Kevin介绍,过河卒每一步都可以选择向前、左、或右移一格,但是不能后退,也不能移出棋盘边界。途中如果经过敌人的棋子,那么敌人的棋子就被吃掉了。

考虑到Lda初学,为了能让游戏不至于过快结束,Kevin决定让Lda的过河卒连走k步,在这k步中Kevin不走棋。Lda希望在这k步中他能吃掉尽可能多的棋子,请问他最多能吃掉Kevin多少棋子呢?

Input
第一行一个正整数T,表示测试数据的组数。接下来每组数据第一行一个正整数k (k ≤ 100),表示Lda可以连续走棋的步数。然后接下来的5行表示棋盘状态,每行一个9个字符的字符串,其中’*’表示没有棋子,’K’表示有Kevin的棋子,’L’表示这里是Lda的过河卒的初始位置(棋盘上有且只有一个’L’)

Output
每组数据输出一行,表示Lda最多能吃掉的棋子数。

Sample Input
3

5

**KKK****

****K****

**K*K**K*

KK****L**

**K******

9

*********

**K******

*********

**K****K*

******L**

8

*********

**K******

*********

**K****K*

******L**

Sample Output
3

3

2

过河卒
这道题利用BFS求解,但是要注意剪枝。不然会造成时间超限,只有和dx处于同行的才有可能进行两次查找,不然只进行一次就行了,不用进行重复查找。

#include<bits/stdc++.h>
using namespace std;
#define CHECK(x,y)(x>=0&&x<5&&y>=0&&y<9)
char room[5][9];
int vis[5][9];
int num,k,sum;
int dx,dy,flag;
struct node
  int x,y;
;

void BFS(int x,int y,int step,int food)

    //cout<<x<<' '<<y<<' '<<food<<endl;
    if(step==k)
        if(food>num)
            num=food;
        return;
    
    if(food==sum)
        num=sum;
        flag=1;
        return;
    
    if(flag==1)return;
    if(step>(dx+1-x)*9+min(dy,8-dy))
        return;
    node start,next;
    start.x=x;
    start.y=y;

    for(int i=0;i<3;i++)
        if(i==0)
            next.x=start.x-1;
            next.y=start.y;
        
        else if(i==1)
            next.x=start.x;
            next.y=start.y-1;
        
        else
            next.x=start.x;
            next.y=start.y+1;
        
        if(CHECK(next.x,next.y)&&((next.x==dx&&vis[next.x][next.y]<2)||(next.x!=dx&&vis[next.x][next.y]<1)))
        vis[next.x][next.y]++;
        if(room[next.x][next.y]=='K')
            room[next.x][next.y]='*';
            BFS(next.x,next.y,step+1,food+1);
            room[next.x][next.y]='K';
        
        else
            BFS(next.x,next.y,step+1,food);
        vis[next.x][next.y]--;
    
  



int main()

    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    int t;
    cin>>t;
    while(t--)
        memset(vis,0,sizeof vis);
        sum=0;
        dx=10;
        flag=0;
        cin>>k;
        for(int i=0;i<5;i++)
            for(int j=0;j<9;j++)
                cin>>room[i][j];
                if(room[i][j]=='L')
                    dx=i;
                    dy=j;
                
                if(room[i][j]=='K'&&dx>=i)
                    sum++;
            
        
        vis[dx][dy]=1;
        //cout<<sum<<endl;
        if(sum==0)
            cout<<0<<endl;
        else
        k=min((dx+2)*9,k);
        num=0;
        BFS(dx,dy,0,0);
        cout<<num<<endl;
        
    
    return 0;

以上是关于过河卒(BFS)的主要内容,如果未能解决你的问题,请参考以下文章

AOJ 763.过河卒

递推2--过河卒(Noip2002)

过河卒

1010 过河卒

DP 过河卒

例3.6过河卒(Noip2002)