[思维][解方程][枚举]Strange_Fractions 第46届icpc区域赛上海站D

59 篇文章 0 订阅
6 篇文章 0 订阅

题目描述

Given a positive fraction p/q​, you should find two positive integers a,b that p/q=a/b+b/a. If no such integers, report it.

输入描述:

The first line contains one integer T (1≤T≤10^5), denoting the number of test cases.

For each test case:

Input one line containing two integers p,q (1≤p,q≤10^7), denoting the given fraction.

输出描述:

For each test case:

If solution exists, output one line containing two integers a,b (1≤a,b≤10^9), or print two zeros in one line if no solution.

输入

2
5 2
5 1

输出

1 2
0 0

题意: 给出p和q,求满足p / q = a / b + b / a的整数a和b,若不存在输出0 0。

分析: 这道题有两种解法,第一种是解方程的思想。将a / b看作整体x,可以把方程化简为x^2 - (p/q)*x + 1 = 0,先判断是否有解,若无解直接输出0 0,若有解需要判断解是否能表示为分数形式,解出一个解x = ((p/q)+根下Δ)/2,这里用任意一个解就行,另一个解就是1/x,要想x表示为分数,那么根下Δ一定是有理数,如果根下Δ无法开方就直接输出0 0,如果可以开方就通分一下得到答案。

另一种方法是枚举,这种方法比较好想,但是时间复杂度稍高一些。原方程化简得到p / q = (a^2+b^2) / (a*b),之后考虑a*b = k*q,a^2+b^2 = k*p,两等式同时成立时k的因子一定是平分给a和b,所以可以给a和b都除以根号k,这之后a和b仍然是整数,这说明若有解那一定存在a是q的某个因子,于是可以枚举q的所有因子。

具体代码如下:

解方程法:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <string>
#define ll long long
using namespace std;

signed main()
{
	int T;
	cin >> T;
	while(T--)
	{
		ll p, q;
		scanf("%lld%lld", &p, &q); 
		if(p*p < 4*q*q) 
			puts("0 0");
		else if((ll)sqrt(p*p-4*q*q)*(ll)sqrt(p*p-4*q*q) != p*p-4*q*q)
			puts("0 0");
		else
			printf("%lld %lld\n", p+(ll)sqrt(p*p-4*q*q), 2*q);
	} 
    return 0;
}

枚举法: 

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <string>
#define ll long long
using namespace std;

signed main()
{
	int T;
	cin >> T;
	while(T--)
	{
		ll p, q;
		scanf("%lld%lld", &p, &q); 
		int t = __gcd(q, p);
		p /= t, q /= t;
		bool flag = false;
		for(int a = 1; a*a <= q; a++)//枚举q的所有因子 
		{
			if(q%a == 0)
			{
				int b = q/a;
				if(p*a*b == q*a*a+q*b*b)
				{
					printf("%lld %lld\n", a, b);
					flag = true;
					break; 
				}
			}
		}
		if(!flag)
			puts("0 0");
	} 
    return 0;
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值