2016ACM/ICPC亚洲区大连站-重现赛 d

首先这道题需要理解一个概念

就是 若 i,j 互质 ,则 i+j 和 i*j 互质

证明如下:(感谢队友的思路)

如果 i j 互质, i+j 和 i*j 不互质,那么  i+j 和 i*j 存在公因数 T ,那么由题意可知 ,T必定为 i 或 j 的因数,同时 T 还为 i + j 的因数,那么假设 i % t == 0, ( i + j ) % t == 0, j 必定为 t 的一个倍数,满足不了i j 互质,故猜想成立。

(证明不严谨。。。有漏洞望大佬们指出)

 

题干很简单

A = X+Y , B= GMD(X,Y) 求 x 最小时的 X Y ,无解输出 No Solition

 

然后先去看本题 A = X+Y , B = GMD(X,Y) 那么有已知的最小公倍数和最大公约数关系可知

B * GCD(X,Y) = X*Y

看到 X*Y已知,X+Y已知,求X Y,很不由自主的就想到了韦达定理。。

那么根据韦达定理 (设 gcd(x,y) = k)    

X+Y = A

X-Y =  sqrt( A*A - 4*k*B)

所以整个问题的难点之一就在于 如何把 k 变成已知量

那么就开始运用我们开头用到的定理。

(i+j) / k =  A / k;

( i*j ) / k =  B / k;

因为  i/k 和 j/k 互质 那么 i/k + j/k 和 i/k * j/k 互质,则有 A/k 和 B/k 互质

那么 k 也就等于 gcd( A, B )

所以这道题也就出来答案了,但是注意,当根号下的数 小于0时 无解,得出的结果不是整数的时候 也是无解(题里说了是整数)

 

 

以下为AC 代码

#include<cstdio>
#include<cmath>
#include<iostream>
using namespace std;
#define ll long long int 
ll gcd(ll a,ll b)
{
	if(a%b)
        return gcd(b,a%b);
    return b;
}
ll max(ll a, ll b)
{
	if(a>b)
	return a;
	else
	return b;
}
ll min(ll a, ll b)
{
	if(a>b)
	return b;
	else
	return a;
}
ll a,b;
ll x,y;
int main()
{
	while(~scanf("%lld%lld",&a,&b))
	{
        ll k=gcd(a,b);
        ll d = a*a-4*b*k;
        ll dd =(ll)sqrt(1.0*d);
        if(d<0)
        {
        	printf("No Solution\n");
        	continue;
		}
		else if((dd+a)%2!=0||dd*dd!=d)
		{
			printf("No Solution\n");
        	continue;
		}
		else
		{
			x = (a + dd) / 2;
			y = a - x;
			printf("%lld %lld\n",min(x,y),max(x,y));
		}
	}
	return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值