Codeforces Round #685 (Div. 2) D
Codeforces Round #685 (Div. 2) D
大意
略...
思路
按照样例的图示,我们不妨考虑可行走的格点范围。
它的边缘一定如下图。
如果走到了边缘的两个格点上,那么下一步一定无法走了,也就是说能够先走到边缘格点的人一定胜利。
我们不妨考虑一下后手必胜的情况下。
此时若先手往右,那么后手往上,或相反。
容易得到一组不等式, 其中 \(a\) 是回合数。
\(\begin{cases} (ak)^2+(ak)^2 \leq d^2 \\ ((a+1)k)^2+(ak)^2 > d^2 \end{cases}\)
即我们找到最大的 \(a\) ,让第一个式子满足,如果第二个式子也满足,那么后手必胜。
那么如果第二个式子不满足呢?
不失一般性,不妨假设先手向上走了一次,然后先手后手交换。
此时原来的后手就处于原来先手的的情况下。
因为
\(\begin{cases} ((a+1)k)^2+((a+1)k)^2 > d^2 \\ ((a+2)k)^2+(ak)^2 > ((a+1)k)^2+((a+1)k)^2 \end{cases}\)
所以此时的后手只需要重复原来后手的方案,一定必胜。
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
#define ll long long
#define ull unsigned long long
#define cint const int&
#define Pi acos(-1)
const int mod = 998244353;
const int inf_int = 0x7fffffff;
const ll inf_ll = 0x7fffffffffffffff;
const double ept = 1e-9;
ll t, d, k;
int main() {
cin >> t;
while(t--) {
cin >> d >> k;
ll a = (ll)(sqrt(((d*d)/(k*k)/2)*1.0));
while((pow(a+1,2)+pow(a,2))*(k*k) <= d*d) ++a;
if(2*a*a*k*k > d*d) cout << "Ashish" << endl;
else cout << "Utkarsh" << endl;
}
return 0;
}