游戏(game)
【问题描述】
小R和小H在玩某个双人联机小游戏,一开始两人所操控的角色各有1点力量值,而在游戏中,每通过一关都会掉落一些力量强化道具。奇怪的是,明明是双人小游戏,每关却都会掉落3个相同的力量强化道具,于是两人决定每关每人先拿一个,剩下一个猜拳决定给谁。一个力量强化道具能使一个角色的力量值变为原来的若干整数倍,同一关卡掉落的道具倍率都相同,而不同的关卡可能不同。小R从攻略上找到了一些会产生特殊效果的力量值组合,他想知道哪些组合是按他们的道具分配方式有可能在通过某关时达成的。
【输入格式】
第一行一个正整数n,表示力量值组合的个数。
接下来n行,每行两个非负整数ai,bi,表示一个力量值组合。
【输出格式】
输出共n行,每行一个”YES”或”NO”表示是否能够达成。
【样例输入】
2
2 4
1 8
【样例输出】
YES
NO
【数据范围】
本题共10个测试点,其中第x个测试点满足n≤max(4x-1,5),ai,bi≤10x-1。
【题解】
由于每一关的掉落三个相同的力量强化道具,所以ai*bi必定为x3,因此先对ai*bi开三次根号,若为不为整数,则直接判NO。
又因为每一个人对于每一关的道具至少使用了一次,因此min(ai,bi)≥开方的结果,作为第二个筛选条件,满足即为YES,否则为NO。
【注意】
1.对于ai.bi中含有0的情况需要特判。
2."YES"和"NO"均为大写。
【代码实现】
1 #include <stdio.h> 2 #define min(a,b)(a<b?a:b) 3 int cbrt(long long x){ 4 long long l=1,r=1000000; 5 while(l<=r){ 6 long long mid=(l+r)/2; 7 long long ans=mid*mid*mid; 8 if(ans==x)return mid; 9 if(ans<x)l=mid+1; 10 if(ans>x)r=mid-1; 11 } 12 return -1; 13 } 14 int main(){ 15 freopen("game.in","r",stdin); 16 freopen("game.out","w",stdout); 17 int n; scanf("%d",&n); 18 while(n--){ 19 long long a,b; 20 scanf("%lld %lld",&a,&b); 21 if(a*b==0&&a+b==0){printf("YES ");continue;} 22 if(a*b==0&&a+b!=0){printf("NO ");continue;} 23 int ans=cbrt(a*b); 24 printf("%s ",(ans!=-1&&min(a,b)>=ans)?"YES":"NO"); 25 } 26 return 0; 27 }