1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| 题意翻译(略长,请耐心看完)
一个独木桥上甲乙二人在玩传送游戏,其规则如下:
1.开始时,甲乙二人分别位于x1,x2处,且甲先手。
2.根据给定的参数a,b,二人可以在桥上传送:每一回合中,假定甲乙现在坐标为x1,x2,那么甲可以传送到[x1+a,x1+b]这一区间内的任一点上,而乙则可以传送到[x2-b,x2-a]上的任一点上,传送时允许跨越对手所在点(毕竟是传送)。
3.胜利的条件:在本方传送后成功到达对手所在点(把对手挤下桥)。
现问:在双方都足够聪明的情况下,谁会胜利?
----
输出格式:
若甲胜利,输出“FIRST”,并在下一行指出此时甲第一步应该传送到的坐标。
若乙胜利,输出“SECOND”。
若比赛无法结束,输出“DRAW”。(注意:仅甲胜利时需要输出第二行。)
-----
数据: 输入仅一行四个整数:x1,x2,a,b。上述量均在[-1e9,1e9]范围内,且保证a≤b
* 特殊地,当a,b异号时,呆在原地不动也是合法操作。
|
题目描述在暗示a,b的符号性很重要,我们就以此分类:
*此处设dis为二人初始位置差,即x2-x1
1.甲乙只能背向前进,根本无法相遇,平局。(dis<0)
2.甲乙相向而行,判断甲能获胜的条件:dis%(a+b)∈[a,b]。
这种情况下,最终一步始终由甲来完成。甲第一步要到x2-(dis*(a+b))*(a+b)
处,乙就无法逃脱。
3.甲乙相向而行,乙能获胜的情况仅有一种:dis%(a+b)=0
这种情况下,乙会恰好完成最后一步从而扼杀甲的下一步。
这种条件下是可以呆在原地的,甲必须一发制敌,否则一定会陷入平局。
1.一发制敌,直接传送到x2处
2.无法到达x2,进入平局。
这种情况比较巧妙,我们考虑把桥倒过来,a,b再取绝对值并易位一下(因为-b≤-a),就可以调用第一种情况的结论了。
讨论完了,上代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
| #include <bits/stdc++.h> #define ri register int #define ll long long using namespace std;
int read() { int num=0; int flg=1; char c=getchar(); while(!isdigit(c)) { if(c=='-') { flg=-1; } c=getchar(); } while(isdigit(c)) { num=(num<<1)+(num<<3)+(c^48); c=getchar(); } return num*flg; }
int dire=1; int main() { int x1=read(); int x2=read(); int dis=x2-x1; int a=read(); int b=read(); if(a<=0&&b<=0) { swap(a,b); a=-a; b=-b; dis=-dis; dire=-dire; } if(a<=0) { if(a<=dis&&dis<=b) { puts("FIRST"); return 0&printf("%d",x2); } else { return 0&(int)puts("DRAW"); } } if(dis<0) { return 0&(int)puts("DRAW"); } else if(dis%(a+b)==0) { return 0&(int)puts("SECOND"); } else if(a<=dis%(a+b)&&dis%(a+b)<=b) { puts("FIRST"); return 0&printf("%d",x2-dire*(dis/(a+b))*(a+b)); } else { return 0&(int)puts("DRAW"); } }
|
规律其实可以由搜索得到,感兴趣的读者可以亲手试试找规律的过程。