hdu5974Math Problem(数学,思维,公式)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5974

分析和思路:

数学题,推公式。这种大量的多组输入暴力解决是不可能的,一般是规律或者推公式。

根据 最大公约*最小公倍=x*y 推出如下解题公式

x*x-a*x+最大公约数*b=0

到了这里发现还多一个未知数最大公约(当然这也是本题最难最关键的部分),其实可以取巧,充分利用给出的条件a,b和样例2结果猜想验证一下,可以很惊喜的发现gcd(a,b)=gcd(x,y)!程序可以完美解方程解决。

至于真正的推导过程有些不太好想,

x+y=a,    x*y/gcd(x,y)=b

令 gcd(x,y)=c 、x=i*c   y=j*c     

i*c+j*c=a ,c*i*j=b   c*(i+j)=a ,

c*i*j=b因为 i j 互质 所以 gcd(a,b)=c=gcd(x,y)!最重要的结论!

 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 #include <iomanip>
 5 #include <vector>
 6 #include <map>
 7 #include <set>
 8 #include <stack>
 9 #include <queue>
10 #include <cstdio>
11 #include <cstring>
12 #include <cmath>
13 using namespace std;
14 typedef long long ll;
15 typedef unsigned long long ull;
16 const int maxn=1e4+5;
17 int vis[maxn];
18 
19 ll gcd(ll a,ll b)
20 {
21     return b?gcd(b,a%b):a;
22 }
23 
24 int main()
25 {
26     ios::sync_with_stdio(false); cin.tie(0);
27     
28     ll a,b;
29     while(cin>>a>>b)
30     {
31         ll c=gcd(a,b);
32         c*=b;
33         ll dt=a*a-4*c;
34         
35         if(dt>=0)//根号下>=0才有解 
36         {
37             ll gdt=sqrt(dt);
38             if(gdt*gdt==dt)//开方是整数 
39             {
40                 ll fz1=a+gdt,fz2=a-gdt;
41                 if(fz1%2==0 && fz2%2==0)//两个分子/2是整数
42                 {
43                     cout<<min(fz1/2,fz2/2)<<' '<<max(fz1/2,fz2/2)<<endl;
44                 }
45                 else
46                 {
47                     cout<<"No Solution"<<endl;
48                 }
49             }
50             else
51             {
52                 cout<<"No Solution"<<endl;
53             }
54         }
55         else
56         {
57             cout<<"No Solution"<<endl;
58         }
59     }
60     
61     return 0;
62 }

完。

猜你喜欢

转载自www.cnblogs.com/redblackk/p/9609768.html