昨晚的力扣E题

链接:
Problem - E - Codeforces

题目背景:双方都绝对理智,让你预测结果的题目。

  • 首先,有A和B两个人,各有一个棋子在棋盘中,棋盘大小为X,Y。
  • 每一轮,A的棋子要往下走一格,假设现在在(x,y),它可以走到(x+1,y)或者(x+1,y-1)或者(x+1,y+1);而B的棋子要往上走一格,假设现在在(x,y),它可以走到(x-1,y)或者(x-1,y-1)或者(x-1,y+1)。(这里限制棋子只能走在棋盘格子中)
  • 初始两个棋子互不重叠,A先手。
  • 在绝对理智的走法情况下,最终,如果A棋子(白棋)可以吃掉B棋子(黑棋),则A胜利;B的棋子吃掉A的,则B胜利;最后吃不掉对方,则平局。

这个输入,6 5  2 2 5 3

6行5列,A的棋子在2行2列,B棋子在 5行3列。

  • 我们首先分析只有一列的情况:
  • 因为A必定向下走一格(可能是斜着走,也可能是直走,但是行数必定加一),而B必定往上走一格(行数必定减一)。可以比较简单的看出,在中间间隔的行数为偶数时,B会赢,反之,奇数时, A会赢。(注意!在计算时,xb-xa的到的结果是,间隔数+1)
  • 然后我们发现,题目中会有平局的情况,通过1,我们也可以发现,其实,当两者的起点的行数确定了,他们相遇的行数也确定了。

  • 我们可以考虑到了列数不是1的情况:

  • 我们可以大概的想象出,如果你是那个会输的人,那么你能争取的最好结果是平局。又因为对方也可以斜着走,于是我们可以知道,如果是列上和对方正对着,或者列号与对方相差-1,都没有逃脱的机会。于是我们的策略是,往左或者右,一个方向走到底,看看能不能逃过对方的范围。

可以看到xb - xa = 3的,相遇时,A走了2步,B走了1步。

可以看到xb - xa = 4的,相遇时,A走了2步,B走了2步。

这样可以算出双方能走到的最大的范围,进而确定,那个会输的是否能不被吃,进而得到平局。

特殊情况:

A本来就和B在同一行,或者,行数大于B。代码表示:xa>=xb,这种情况,只能是平局。

代码:

>>

#include<bits/stdc++.h>

using namespace std;


void solve(){
    int x,y;
    cin>>x>>y;
    int a,aa,b,bb;
    cin>>a>>aa>>b>>bb;
    
    bool f = 0;
    if(a>=b){
//        cout<<"1"<<"\n";
        cout<<"Draw";
        return;
    }
    else{
        int k = b-a;
        if((k&1)==0){// b可能赢,或者平 
            f = 1; 
        }
        
        int am,ax,bm,bx;
        // 多少步后相遇。 
        int ka = (k+1)/2;
        int kb = k-ka;
//        cout<<"ka="<<ka<<"\n";
//        cout<<"kb="<<kb<<"\n";
        // 算出最远跑多远。 
        am = max(aa-ka,1);
        ax = min(aa+ka,y);
        bm = max(bb-kb,1);
        bx = min(bb+kb,y);
        
        bool fm = am<bm;
        bool fx = ax>bx;
        
        bool ffm = bm<am;//am<bm-1//am>bm
        bool ffx = bx>ax;
        if(f){
            if(fx||fm){
                cout<<"Draw";
            }
            else{
                cout<<"Bob";
            }
        }
        else{
            if(ffx||ffm){
                cout<<"Draw";
            }
            else{
                cout<<"Alice";
            }
        }
    }
    
    
    

int main(){
    int n;
    cin>>n;
    while(n--){
        solve();
        cout<<"\n";
    }
    
    
    return 0;

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值