ZCMU-1951:y和wjw的无聊游戏(数学推导)

Problem H: ly和wjw的无聊游戏

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 60  Solved: 20
[Submit][Status][Web Board]

Description

 众所周知,ly和wjw是好朋友,某天特别无聊,他们想自己编一个游戏代码,无奈水平有限,只会写个random每次输出一个随机数,于是他们自己制定了一个游戏规则
游戏由多轮组成,每一轮中由计算机输出一个自然数ki,然后ly和wjw会同时喊出一个数字,谁喊出的数字更靠近这个ki就获胜,获胜的人的得分会乘上ki^2,失败者的得分乘上ki.
虽然这个游戏很无聊,但是为了打发时间,ly和wjw居然玩了一下午,但是由于记录游戏步骤的ly弄丢了他们记录T场游戏的笔记本,但是好在wjw还依稀记得每场比赛最终的结局是ly获得了ai分,wjw获得了bi分。但是他的记忆是模糊的,他希望能够验证没对ai和bi是否正确。
每场游戏一开始ly和wjw的积分都是1.
wjw和ly不想太麻烦你,他们只想知道对于每组ai和bi的结局是否是一个正确的最终得分。

Input

 第一行输入一个T,表示总共进行了TT组游戏(T≤500000)(T≤500000)
接下来的TT行,每行两个整数aiai和bibi表示wjw记得的每一场比赛两人的最终得分(1<=ai,bi<=109)(1<=ai,bi<=109)

Output

 对于每一对aiai和bibi,如果这对最终得分是正确的,那么输出"OkOk",否则输出"ErrorError".

Sample Input

4

16 16

2 4

1 1

18 19

Sample Output

Error

Ok

Ok

Error

HINT

 

【解析】

这题,结果推过程。。。。逆向思维的话要用到方程的思想吧。

首先对已知的分数a,b很容易得出

a = k1^(x1)*k2^(x2)*.......*ki^(xi)

b = k1^(y1)*k2^(y2)*.......*ki^(yi)

其中对每组xi+yi=3。

所以a*b=(k1*k2*.......*ki)^3,即a*b必须是一个数的三次方。

但是,因为赢的人是乘以ki^2,输的人是乘以ki,所以对每个ki都是a,b的因子,否则就会出现一个是乘以ki^0,一个乘以ki^3,不符合题意。翻译成代码就是a*a%b==0,b*b%a==0(不知道是a赢还是b赢,所以是平方求余)。

#include 
using namespace std;
bool check(long long n)//看是否存在一个数mid,满足mid^3==a*b;
{
	int left = 0, right = 1000000;
	long long mid;
	while (left <= right)
	{
		mid = (left + right) / 2;
		if (mid*mid*mid == n)return 1;
		if (mid*mid*mid < n)
			left = mid + 1;
		else right = mid - 1;
	}
	return 0;
}
int main()
{
	int t;
	scanf("%d", &t);
	while (t--)
	{
		long long a, b;
		scanf("%lld%lld", &a, &b);
		if (a*a%b == 0 && b*b%a == 0 && check(a*b))//重点
			printf("Ok\n");
		else printf("Error\n");
	}
	return 0;
}

 

你可能感兴趣的:(oj)