[NOIP模拟赛]棋子游戏

来源:互联网 发布:红蜘蛛软件破解网络 编辑:程序博客网 时间:2024/05/21 08:42

题目描述

DaisyStella玩一个游戏。

游戏在一个无限长的一维坐标轴上,每个玩家有一枚棋子。一开始Daisy的棋子在x=0的位置,Stella的棋子在x=d的位置。

每个棋子有两个属性:最大移动距离,攻击范围。Daisy的棋子的最大移动距离是mov1,攻击范围是rng1;Stella的棋子的最大移动距离是mov1,攻击范围是rng1。

两人轮流操作,Daisy先走。每轮当前玩家移动己方棋子,但移动距离不可超过该棋子的最大移动距离(移动距离必须是整数,可以不动)。然后,当前玩家检查对方棋子是否在己方棋子攻击范围内,如果是,当前选手获胜,否则游戏继续。

已知正整数mov1,rng1,mov2,rng2,d。求出双方都使用最优策略下谁能获胜,或者平局。


输入格式

多组数据,首先是一个整数T(5≤T≤20)表示有T组测试数据,每组测试数据为:

第一行:5个整数,分别表示mov1,rng1,mov2,rng2,d。(1≤mov1,rng1,mov2,rng2,d≤10^9


输出格式

共T行,每行一个字符串,如果Daisy胜,输出"Daisy",如果Stella胜,输出"Stella",平局输出"Draw"。


输入样例

17 19 21 31 41


输出样例

Draw



题解:

①首先判断Daisy能否在第一轮击败Stella。

 

②mov1+rng1==mov2+rng2的时候一定是平局;

先明确一个结论:Daisy能击败Stella的必要条件是mov1+rng1>mov2+rng2(Stella击败Daisy同理);

证明:假设mov1+rng1≤mov2+rng2且Daisy赢了(非第一轮),说明Daisy最后一次移动之前与Stella的距离dis≤mov1+rng1;

再考虑Stella最后一次移动之前与Daisy的距离dis‘:

若dis’>dis,那么Stella不可能蠢到缩短距离去让Daisy打,因为这样会直接输掉比赛;

若dis’<dis,那么Stella在这时就已经能干掉Daisy了,不可能蠢到增长距离,还只增长到让Daisy刚好能打到自己。

所以mov1+rng1==mov2+rng2的时候一定是平局,因为双方都无法靠近对方。

 

③若mov1+rng1>mov2+rng2,这时只要判断答案是Daisy胜还是平局。

因为Daisy第一轮无法击败Stella,Stella也不可能击败Daisy,所以Stella会跑,Daisy会追,所以Daisy胜利的其中一个条件是mov1>mov2。

但Daisy在追的时候还要防止Stella突然回头攻击,因此要保持与Stella的距离dis>mov2+rng2,所以条件二是mov1+rng1≥1+rng2+mov2+mov2。

 

④mov1+rng1<mov2+rng2,情况类似,但要先判断Stella能否在第二轮击败Daisy,不行再套用③的判断方式。


#include<cstdio> int T, mov1, mov2, rng1, rng2, d;int main() {    for( scanf( "%d", &T ); T; T-- ) {         scanf( "%d%d", &mov1, &mov2 ); scanf( "%d%d%d", &rng1, &rng2, &d );         if( mov1+rng1>=d ) printf( "Daisy\n" );         else if( mov1+rng1==mov2+rng2 ) printf( "Draw\n" );         else if( mov1+rng1>mov2+rng2 ) {             if( mov1>mov2 && mov1+rng1>=1+rng2+mov2+mov2 ) printf( "Daisy\n" );             else printf( "Draw\n" );         }         else if( mov1+rng1<mov2+rng2 ) {             if( mov1+d<=mov2+rng2 ) printf( "Stella\n" );             else if( mov2>mov1 && mov2+rng2>=1+rng1+mov1+mov1 ) printf( "Stella\n" );             else printf( "Draw\n" );         }     }     return 0; }


原创粉丝点击