过河卒(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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值