Codeforces Round #685 (Div. 2) D
阿新 • • 發佈:2020-11-22
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; }