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

时间:2021-09-15 17:01:59

题目分析:

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

$\frac{a}{b} < \frac{p}{q} < \frac{c}{d}$

当a=0时,答案等于$\frac{1}{\lfloor \frac{d}{c} \rfloor + 1}$
当a>=b时,可以考虑前后同减去一个数化为真分数,再加上

当c>d时,因为不满足一二,所以可以直接令答案等于$\frac{1}{1}$

否则分子分母取倒,再倒回来

代码:

 #include<bits/stdc++.h>
using namespace std; const int maxn = ; int n,C1,C2;
int a[maxn]; pair<int,int> p1,p2; void comp(pair<int,int> alpha,pair<int,int> beta){
if(1ll*alpha.first*beta.second >= 1ll*alpha.second*beta.first)
p1 = beta;
} pair<int,int> euchild(pair<int,int> alpha,pair<int,int> beta){
if(alpha.first == ) return make_pair(,beta.second/beta.first+);
if(alpha.first >= alpha.second){
int lw = alpha.first/alpha.second,hh = beta.second;
pair<int,int> jh = euchild(make_pair(alpha.first%alpha.second,alpha.second),make_pair(beta.first-lw*hh,hh));
jh.first += jh.second*lw;
return jh;
}
if(beta.first > beta.second) return make_pair(,);
swap(beta.first,beta.second);swap(alpha.first,alpha.second);
pair<int,int> jh = euchild(beta,alpha);
swap(jh.first,jh.second);
return jh;
} void work(){
if(n&){puts("-1");return;}
p1 = make_pair(,);
int a1 = ,a2 = ;
for(int i=;i<n;i++){
if(i&) a1 += a[i];
else a2 += a[i];
comp(p1,make_pair(a1,a2));
}
a2 += a[n]; p2 = make_pair(a2,a1); swap(p1.first,p1.second);
if(1ll*p1.first*p2.second > 1ll*p2.first*p1.second){puts("-1");return;}
pair<int,int> ans = euchild(p1,p2);
if(ans.first <= C1 && ans.second <= C2){
printf("%d %d\n",ans.first,ans.second);
}else puts("-1");
} int main(){
int Tmp; scanf("%d",&Tmp);
while(Tmp--){
scanf("%d%d%d",&n,&C1,&C2);
for(int i=;i<=n;i++) scanf("%d",&a[i]);
work();
}
return ;
}