F:跳蛙【2019北大夏令营F】

F:跳蛙【2019夏令营F】找不到提交入口正确性未知

  • 查看

  • 提交

  • 统计

  • 提问

  • 总时间限制:

    1000ms

  • 内存限制:

    65536kB

  • 描述

    在一个 1*n 的棋盘上生活着若干只青蛙:有恰好一只青蛙王和若干只(可能没有)普通青蛙。

    我们用 A 表示青蛙王,B 表示普通青蛙,. 表示空地。

    有一天,青蛙王醒来的时候发现它处在棋盘的最左侧,它想要跳到棋盘的最右侧。它可以指挥青蛙们来行动

    每一时刻可以选择下列操作中的一个进行操作:

    1. 对于青蛙王,如果它右侧相邻的格子是普通青蛙,且它右侧有空地的话,它可以跳到右侧第一个空地。
    2. 对于青蛙王,如果它左侧相邻的格子是普通青蛙,且它的左侧有空地的话,它可以跳到左侧第一个空地。
    3. 对于普通青蛙,如果它右侧相邻的格子是空地,它可以移动到这个空地。
    4. 对于普通青蛙,如果它左侧相邻的格子是空地,它可以移动到这个空地。

    在移动的过程中,任意两只青蛙都不能同时移动,且任意一只青蛙不能移动出棋盘。现在给出初始时每一只青蛙的位置,问青蛙王能否到达棋盘的最右侧

  • 输入

    输入包含多组数据。 每组数据第一行是一个整数 n(2<=n <= 10) 表示棋盘的大小。 第二行是一个长度为 n 的字符串从左到右表示棋盘的状态。保证第一个字符是 A,字符串只可能包含 AB. 三种字符,且恰好包含一个 A。 输入以 n=0 结束。

  • 输出

    对于每组数据,如果青蛙王能到达最右边,则输出 Y,否则输出 N。

  • 样例输入

    6
    A.B..B
    6
    A.B...
    6
    ABBBBB
    2
    A.
    0
    
  • 样例输出

    Y
    N
    N
    N
    

题解1

  • 深搜,(青蛙王左边的普通青蛙数目lf,右边的普通青蛙数目rf,青蛙王当前位置start),其中**(lf, start)标识了一个状态**(lf和start都相同的出发状态的接下来的搜索过程是一样的)

    • 如果左边有空位,则可以指挥[1,lf]i只青蛙移动到A的左边,然后A可以跳跃到这i只连续青蛙的左边;右边同理
    • n<=10则lf和start<=10,因此lf*100+start可以唯一标识所以状态,且范围<1100
  • 解释样例1

    AB-B-- //指挥成这样
    -BAB-- 
    -B-BA-
    --BBA- //指挥成这样 
    -ABB--
    -AB-B- //指挥成这样 
    --B-BA
    
#define MAX_STATE 1100
int visited[MAX_STATE]={0};
//idx from 1
int n;
bool solve(int lf, int rf, int start)
{
    if(start==n){
        return 1;
    }
    if(visited[lf*100+start]){
        return 0;
    }
    visited[lf*100+start]=1;
    //left
    if(start-lf>1){
        for(int i=1; i<=lf; ++i){
            if(solve(lf-i, rf+i, start-i-1)){
                return 1;
            }
        }
    }
    //right
    if(start+rf<n){
        for(int i=1; i<=rf; ++i){
            if(solve(lf+i, rf-i, start+i+1)){
                return 1;
            }
        }
    }
    //no solution
    return 0;
}

int main()
{
    while(cin>>n && n){
        int lf=0,rf=0;
        char c;
        for(int i=0; i<n; ++i){
            cin>>c;
            if(c=='B'){
                ++rf;
            }
        }
        if(solve(lf,rf,1)){
            cout<<"Y"<<endl;
        }
        else{
            cout<<"N"<<endl;
        }
    }
    return 0;
}

题解2

  • 看到大神的解答:只要有空位且普通青蛙数目>=2就一定有解

    • 没有证明,不懂

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值