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 }