AcWing 1223. 最大比例

原题链接

考察:最大公约数

思路:

        设原序列为a1,a2,a3...an,公比为(q/p)t,题目给的样例是在a数组中随机抽取一些数,形成新序列 b1,b2,b3...bn,可以发现b2/b1 = (q/p)k1 b3/b1 = (q/p)k2  ,显而易见k1与k2都是t的倍数,对k求最大公约数就是t.

       在未知指数的情况下,求指数的最大公约数用辗转相减法更方便.gcd(ax,ay) = agcd(x,y) = agcd(y,x-y) = gcd(ay,ax-y)  = gcd(ay,ax/ay).如果用辗转相除法只能是%,%涉及分数,需要开根号.

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <vector>
 4 using namespace std;
 5 const int N = 110;
 6 typedef long long LL;
 7 typedef pair<LL,LL> PLL;
 8 vector<LL> v;
 9 PLL p[N];
10 LL gcd_sub(LL a,LL b)
11 {
12     if(a<b) swap(a,b);
13     if(b==1) return a;
14     return gcd_sub(b,a/b);
15 }
16 LL gcd(LL a,LL b)
17 {
18     return b?gcd(b,a%b):a;
19 }
20 int main()
21 {
22     int n;
23     scanf("%d",&n);
24     for(int i=1;i<=n;i++)
25     {
26         LL x; scanf("%lld",&x);
27         v.push_back(x);
28     }
29     sort(v.begin(),v.end());
30     v.erase(unique(v.begin(),v.end()),v.end());
31     if(v.size()==1) {printf("%d/%d\n",1,1); return 0;}
32     for(int i=1;i<v.size();i++)
33     {
34         LL d = gcd(v[i],v[0]);
35         p[i].first = v[i]/d;
36         p[i].second = v[0]/d;
37     }
38     LL d1 = p[1].first,d2 = p[1].second;
39     for(int i=1;i<v.size();i++)
40         d1 = gcd_sub(d1,p[i].first),d2 = gcd_sub(d2,p[i].second);
41     printf("%lld/%lld\n",d1,d2);
42     return 0;
43 }

 

posted @ 2021-02-28 19:28  acmloser  阅读(68)  评论(0编辑  收藏  举报