P2118 Billy ♂ Simplify

p2118 Billy ♂ Simplify

Title description

On social media, you will often see polls and the results of whether a certain opinion agrees or not. For example, if there are 14,981,498 people who support a certain point of view and 902,902 who oppose it, then the ratio of approval to opposition can be simply written as 1498: 9021498: 902.

However, if the survey results are presented in this way, most people will certainly not be satisfied. Because the value of this ratio is too large, it is difficult to see their relationship at a glance. For the above example, if the ratio is recorded as 5: 35: 3, although there is a certain error from the actual result, it can still reflect the survey results more accurately, and it is also more intuitive.

Now we give the number of supporters A, the number of opponents B B , and an upper limit L L , please simplify A A to B B to A A 'than B B ', requiring that A A 'and B B ' are not greater than L L and A A 'and B B ' are relatively prime (the greatest common divisor of two integers is 11), A A '/ B / B ' ≥ A / B≥ A / B and A A '/ B / B The value of '-A / B− A / B is as small as possible.

(This topic is 2014 NOIP Popularization T2)

Input format

One line, containing three integers A, B, L A , B , L , each two integers are separated by a space, indicating the number of supporters, the number of opponents and the upper limit.

Output format

A line, containing two integers A A ', B B ', separated by a space in the middle, indicating the simplified ratio.

Sample input and output

Input

1498 902 10

Output

5 3

Instructions / Tips

1 ≤ A ≤ 1,000,000

1 ≤ B ≤ 1,000,000

1 ≤ L ≤ 100

A/B ≤ L

answer

Since L is less than 100, the numerator and denominator can be enumerated, and the smallest difference can be found by comparing the difference between the ratio and the ratio of A and B.

Optimize on this algorithm, and finally use the numerator and denominator at the same time divided by GCD to ensure mutual prime.

The remaining details will be commented in the code.

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int a, b, l, d, A, B;
double ans[105][105], t, T = 9999999/*T是用来和新比值和目标比值的差的大小作比较的, 存储绝对值最小的差*/;	
bool flag = 0;
int gcd(int x, int y) {
	if (y == 0) {
		return x;
	}
	x %= y;
	return gcd(y, x);
}
int main() {
	cin >> a >> b >> l;
	A = l;
	B = 1;//防止溢出导致没有答案的初始化
	if (a < b) {//保证a>b
		flag = 1;
		T = -T;//这里的T变成负数, 因为a,b做了互换, 所以新比值-原比值<0, 所以T也要小于0.
		swap(a,b);
		A = 1;
		B = l;
	}
	ans[0][0] = 1.000000000000 * a / b;//用double存比值
	if (a < l) {//当本来就能用a,b作为答案的情况单独处理
		d = gcd(a, b);//注意使其互质
		a /= d;
		b /= d;
		if (flag) {//详见最后的输出注释
			cout << b << " " << a << endl;
			return 0;
		}
		cout << a << " " << b << endl;
		return 0;
	}
	for (int i = 1; i <= l; i++) {//枚举分子
		for (int j = 1; j < i; j++) {//枚举分母,因为a>b,所以分子>分母
			ans[i][j] = 1.00000000000 * i / j;//求出比值
			if (flag) {//原a<b
				if (ans[i][j] < ans[0][0]) {//这时如果保证了原来的a/b<=A/B, 就需要让交换处理后的a/b>=A/B, 才能保证答案符合要求
					t = ans[i][j] - ans[0][0];//这个t是负数
					if (t > T) {//负数越大, 绝对值越小, 差距越小
						T = t;
						A = i;
						B = j;//更新答案
					}
				}
			}
			else {//原a>b
				if (ans[i][j] > ans[0][0]) {//这时要满足题目要求, A/B>=a/b
					t = ans[i][j] - ans[0][0];
					if (t < T) {//差距更小
						T = t;
						A = i;
						B = j;//更新答案
					}
				}
			}
		}
	}
	d = gcd(A, B);
	A /= d;
	B /= d;//保证答案互质
	if (flag) {//原a<b, 一开始进行了交换, 这时应该回到原来的顺序输出
		cout << B << " " << A << endl;
		return 0;
	}
	cout << A << " " << B << endl;//正常输出
	return 0;
}

Guess you like

Origin www.cnblogs.com/Wild-Donkey/p/12723382.html