codechef EBAIT Election Bait【欧几里得算法】

题目分析:

欧几里得算法来处理一类分数问题,分数问题的形式如下

$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 }
原文地址:https://www.cnblogs.com/Menhera/p/10263681.html