题目分析:
欧几里得算法来处理一类分数问题,分数问题的形式如下
$frac{a}{b} < frac{p}{q} < frac{c}{d}$
当a=0时,答案等于$frac{1}{lfloor frac{d}{c}
floor + 1}$
当a>=b时,可以考虑前后同减去一个数化为真分数,再加上
当c>d时,因为不满足一二,所以可以直接令答案等于$frac{1}{1}$
否则分子分母取倒,再倒回来
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 1020000; 5 6 int n,C1,C2; 7 int a[maxn]; 8 9 pair<int,int> p1,p2; 10 11 void comp(pair<int,int> alpha,pair<int,int> beta){ 12 if(1ll*alpha.first*beta.second >= 1ll*alpha.second*beta.first) 13 p1 = beta; 14 } 15 16 pair<int,int> euchild(pair<int,int> alpha,pair<int,int> beta){ 17 if(alpha.first == 0) return make_pair(1,beta.second/beta.first+1); 18 if(alpha.first >= alpha.second){ 19 int lw = alpha.first/alpha.second,hh = beta.second; 20 pair<int,int> jh = euchild(make_pair(alpha.first%alpha.second,alpha.second),make_pair(beta.first-lw*hh,hh)); 21 jh.first += jh.second*lw; 22 return jh; 23 } 24 if(beta.first > beta.second) return make_pair(1,1); 25 swap(beta.first,beta.second);swap(alpha.first,alpha.second); 26 pair<int,int> jh = euchild(beta,alpha); 27 swap(jh.first,jh.second); 28 return jh; 29 } 30 31 void work(){ 32 if(n&1){puts("-1");return;} 33 p1 = make_pair(1,0); 34 int a1 = 0,a2 = 0; 35 for(int i=1;i<n;i++){ 36 if(i&1) a1 += a[i]; 37 else a2 += a[i]; 38 comp(p1,make_pair(a1,a2)); 39 } 40 a2 += a[n]; p2 = make_pair(a2,a1); swap(p1.first,p1.second); 41 if(1ll*p1.first*p2.second > 1ll*p2.first*p1.second){puts("-1");return;} 42 pair<int,int> ans = euchild(p1,p2); 43 if(ans.first <= C1 && ans.second <= C2){ 44 printf("%d %d ",ans.first,ans.second); 45 }else puts("-1"); 46 } 47 48 int main(){ 49 int Tmp; scanf("%d",&Tmp); 50 while(Tmp--){ 51 scanf("%d%d%d",&n,&C1,&C2); 52 for(int i=1;i<=n;i++) scanf("%d",&a[i]); 53 work(); 54 } 55 return 0; 56 }