您的位置:首页 > 其它

2019hdu暑假多校训练赛第五场1004 equation hdu 6627(数学思维)

2019-08-05 18:27 337 查看

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6627

题意:给出长度为n的两个序列a[i],b[i],再给定一个C值,让求出所有满足      的x的解,输出结果为分数形式。

数据范围:1≤T≤50,1≤N≤1e5 , 1≤ai≤1000, −1000≤bi≤1000,1≤C≤1e9

 

思路:我们可以设定 ,此时相当于我们获得了n个带绝对值的一次函数,这时候因为带了绝对值所以每个函数的图像都是对勾形式的且关于 左右对称,这时候我们只需要按照对称轴从左到右枚举每两个对称轴的中间位置,看是否存在 ((C-sumb)/suma)这样的解刚好在两个对称轴中间,无穷解的情况及C-sumb==0&&suma==0

[code]#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
int n,m,t,k;
ll C;
struct p{
ll a,b;
double mid;
}xx
;
bool cmp(p aa,p bb){
return aa.mid<bb.mid;
}
set<pair<ll,ll> >S;
struct pp{
ll zi,mu;
double num;
}yy[N*10];
bool cmp2(pp aa, pp bb){
return aa.num<bb.num;
}
int main(){
scanf("%d",&t);
while(t--){
S.clear();
scanf("%d%lld",&n,&C);
ll suma=0,sumb=0;
for(int i=1;i<=n;i++){
scanf("%lld%lld",&xx[i].a,&xx[i].b);
xx[i].mid=-1.0*xx[i].b/xx[i].a;
suma+=xx[i].a,sumb+=xx[i].b;
}
sort(xx+1,xx+n+1,cmp);
xx[n+1].mid=10000000.0;
suma=-suma,sumb=-sumb;
bool flag=0;
for(int i=1;i<=n;i++){
ll zi=abs(C-sumb);
ll mu=abs(suma);
ll z=__gcd(zi,mu);
if(suma==0&&sumb==C){
flag=1;
break;
}
if(i==1&&1.0*(C-sumb)/suma<=xx[i].mid){
if((C-sumb)*suma<0)S.insert(make_pair(-zi/z,mu/z));
else S.insert(make_pair(zi/z,mu/z));
}
else if(1.0*(C-sumb)/suma<=xx[i].mid&&1.0*(C-sumb)/suma>=xx[i-1].mid){
if((C-sumb)*suma<0)S.insert(make_pair(-zi/z,mu/z));
else S.insert(make_pair(zi/z,mu/z));
}
suma=suma+2*xx[i].a,sumb=sumb+2*xx[i].b;
while(xx[i+1].mid==xx[i].mid){
i++;
suma=suma+2*xx[i].a,sumb=sumb+2*xx[i].b;
}
if(flag)break;
}
ll zi=abs(C-sumb);
ll mu=abs(suma);
ll z=__gcd(zi,mu);
if(suma==0&&sumb==C)flag=1;
if(flag==0&&1.0*(C-sumb)/suma>=xx
.mid){
if((C-sumb)*suma<0)S.insert(make_pair(-zi/z,mu/z));
else S.insert(make_pair(zi/z,mu/z));
}
if(flag)printf("-1");
else{
int tot=0;
cout<<S.size();
set<pair<ll,ll> >::iterator it=S.begin();
for(;it!=S.end();it++){
yy[++tot].zi=it->first,yy[tot].mu=it->second;
yy[tot].num=1.0*yy[tot].zi/yy[tot].mu;
}
sort(yy+1,yy+tot+1,cmp2);
for(int i=1;i<=tot;i++){
printf(" %lld/%lld",yy[i].zi,yy[i].mu);
}
}
cout<<endl;
}
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: