Codeforces Round #685 (Div. 2) D. Circle Game

Codeforces Round #685 (Div. 2) D. Circle Game

题意:

A和U两个人玩游戏,在一个二维平面上,初始有一点在 ( 0 , 0 ) (0,0) (0,0)。A先手,每人每步将横坐标或者纵坐标加上 k k k。并且移动后的点 ( x , y ) (x,y) (x,y)满足 x 2 + y 2 ≤ d 2 x^2+y^2\le d^2 x2+y2d2,如果不能行动的话,就失败。问给定 d , k d,k d,k,谁胜利。

思路:

我们可以假设在某一点的时候,两人都朝一个方向走,那么谁是胜者就是可以确定的。为了避免失败,后手应该朝先手相反的方向走。也就是说,如果先手走 x x x,那么后手走 y y y轴;先手走 y y y轴,后手走 x x x轴。
就相当于一人走 x x x轴,一人走 y y y轴。假设A最多沿 x x x轴走 a a a步,U最多沿 y y y轴走 b b b步,可以得到 a = b a=b a=b或者 a = b + 1 a=b+1 a=b+1。那么可以枚举 b b b,判断 [ ( b + 1 ) k ] 2 + ( b k ) 2 > d 2 [(b+1)k]^2+(bk)^2\gt d^2 [(b+1)k]2+(bk)2>d2是否成立,如果成立,说明最后一步是U走的,U胜;否则A胜。
另外一种不等式化简的思路:
∵ ( a k ) 2 + ( b k ) 2 ≤ d 2 \because(ak)^2+(bk)^2\le d^2 (ak)2+(bk)2d2
∴ k 2 ( a 2 + b 2 ) ≤ d 2 \therefore k^2(a^2+b^2)\le d^2 k2(a2+b2)d2
∴ a 2 + b 2 ≤ d 2 k 2 \therefore a^2+b^2\le \cfrac{d^2}{k^2} a2+b2k2d2
∵ ( a + b 2 ) 2 ≤ a 2 + b 2 2 \because \left(\cfrac{a+b}{2}\right)^2\le \cfrac{a^2+b^2}{2} (2a+b)22a2+b2
我们又可以知道在 a = b a=b a=b的时候,取等号。
∴ ( 2 b ) 2 2 = 2 b 2 ≤ d 2 k 2 \therefore \cfrac{(2b)^2}{2}=2b^2\le\cfrac{d^2}{k^2} 2(2b)2=2b2k2d2
∴ 2 b ≤ 2 d 2 k 2 \therefore 2b\le\sqrt\cfrac{2d^2}{k^2} 2bk22d2
∴ b = ⌊ d 2 2 k 2 ⌋ \therefore b=\lfloor\sqrt\cfrac{d^2}{2k^2}\rfloor b=2k2d2
判断 a = b + 1 a=b+1 a=b+1的时候 ( a k ) 2 + ( b k ) 2 ≤ d 2 (ak)^2+(bk)^2\le d^2 (ak)2+(bk)2d2是否满足。

代码:

#include<bits/stdc++.h>
#define pii pair<int,int>
#define int long long
#define cl(x,y) memset(x,y,sizeof(x))
#define loop(x,y,z) for(x=y;x<=z;x++)
#define reve(x,y,z)	for(x=y;x>=z;x--)
#define ct cerr<<"Time elapsed:"<<1.0*clock()/CLOCKS_PER_SEC<<"s.\n";
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define all(x) x.begin(),x.end()
#define lson x<<1,l,mid
#define rson x<<1|1,mid+1,r
#define INF 1e18
const int N=1e6+10;
const int mod=1e9+7;
const int inf=0x3f3f3f3f;
const double eps=1e-8;
const double pi=acos(-1);
using namespace std;

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	int t;
	cin>>t;
	while(t--)
	{
		int d,k;
		cin>>d>>k;
		double p=sqrt(d*d/(2.0*k*k));
		int v=p;
		cout<<(v*k*v*k+(v+1)*k*(v+1)*k>d*d?"Utkarsh":"Ashish")<<endl; 
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值