题目链接
题意:
Vanya每秒打x次,Vova每秒打y次,询问每次最后一击是谁打的
思路:
Vanya 1/x 秒打一次,Vova 1/y秒打一次
同乘x * y后为y:x,x与y的最小公倍数为x*y/gcd(x,y),还原后为1/gcd(x,y),即每1/gcd(x,y) 秒两人会同时打一次,则每个周期T一共打了x/gcd(x,y)+y/gcd(x,y)
在x,y中选择小的那个,建一个num数组,num[i]表示一个周期内Vanya或Vova打了第i下时两人一共所打的次数(一开始没有选择小的导致爆了long long,然后用double结果又被G++卡了精度orz)
之后对于每次查询只需要模T后二分查找即可得出答案。
题目挺水,就是脑子不好使。。。
代码如下
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
ll num[1000010];
int main()
{
int n,x,y;
scanf("%d%d%d",&n,&x,&y);
int t=__gcd(x,y);
int T=x/t+y/t;
int flag=0;
if(x>y)
{
x+=y;
y=x-y;
x=x-y;
flag=1;
}
for(ll i=1;i<=x/t;i++) num[i]=(y*i/x)+ i;
for(int i=1;i<=n;i++)
{
int h;
scanf("%d",&h);
h=h%T;
if(h==T-1||h==0) printf("Both\n");
else
{
int k=lower_bound(num+1,num+x/t+1,h)-num;
if(!flag)
{
if(num[k]==h) printf("Vanya\n");
else printf("Vova\n");
}
else
{
if(num[k]==h) printf("Vova\n");
else printf("Vanya\n");
}
}
}
}
.