题目背景:双方都绝对理智,让你预测结果的题目。
- 首先,有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;
}