hdu6627 equation(讨论)

题目链接

题意:给你一个一个式子 i = 1 n a i x + b i = c \sum_{i=1}^n|a_i*x+b_i|=c i=1naix+bi=c,让你求出x的所有解,从小到大排序。
思路:因为给的n个一次函数的零点是唯一的,我们对n个函数按照零点从大到小排序,然后遍历n个点,显然当遍历到k时,[1,k]都会取得相反数,然后我们判断当前解是否合法,再判断是否是无穷多解。
讨论完成之后就是对所有解排序,去个重就行了

#include<bits/stdc++.h>

#define LL long long
#define fi first
#define se second
#define mp make_pair
#define pb push_back

using namespace std;

LL gcd(LL a,LL b){return b?gcd(b,a%b):a;}
LL lcm(LL a,LL b){return a/gcd(a,b)*b;}
LL powmod(LL a,LL b,LL MOD){LL ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
const int N = 1e5 +11;
int t,n,a[N],b[N];
struct uzi
{
    LL a,b;
    int i;
    bool operator <(const uzi &t)const{
        return a*t.b>b*t.a;
    }
}p[N],ans[N];
int cnt,c;
LL L[N],R[N];
int cmp(uzi x,uzi y){
    return x.a*y.b<x.b*y.a;
}
int main(){
     // freopen("in.txt","r",stdin);
    ios::sync_with_stdio(false);
    for(cin>>t;t;t--){
        cin>>n>>c;cnt=0;
        int sta=0;
        for(int i=1;i<=n;i++)cin>>a[i]>>b[i],p[i].a=-b[i],p[i].b=a[i],p[i].i=i;
        sort(p+1,p+1+n);
        for(int i=1;i<=n;i++)L[i]=L[i-1]+a[p[i].i],R[i]=R[i-1]+b[p[i].i];
        for(int i=0;i<=n;i++){//[0,i]为负
            LL la=L[i],ra=R[i];
            LL lb=L[n]-L[i],rb=R[n]-R[i];
                LL da=c-(rb-ra);
                LL ad=lb-la;
                if(ad<0)da=-da,ad=-ad;
                LL x=gcd(abs(da),abs(ad));
            if(i!=n){
                if(da*a[p[i+1].i]+ad*b[p[i+1].i]<0){
                    continue;
                }                
            }
            if(da*a[p[i].i]+ad*b[p[i].i]>0)continue;
            if(lb-la!=0){
                da/=x;
                ad/=x;
                ans[++cnt]={da,ad};
            }else {sta=1;break;}
        }
        if(sta)cout<<-1<<'\n';
        else{
            if(!cnt){cout<<"0\n";continue;}
            int pp=0;
            sort(ans+1,ans+1+cnt,cmp);
            for(int i=1;i<=cnt;i++){
                if(i>1){
                    if(ans[i].a==ans[i-1].a&&ans[i].b==ans[i-1].b)continue;
                }
                pp++;
            }
            cout<<pp<<' ';
            int cn=1;
            for(int i=1;i<=cnt;i++){
                if(i>1){
                    if(ans[i].a==ans[i-1].a&&ans[i].b==ans[i-1].b){
                        continue;
                    }
                }
                if(ans[i].a==0)cout<<"0/1";
                else cout<<ans[i].a<<'/'<<ans[i].b;
                if(pp==cn)cout<<'\n';
                else cout<<' ';
                cn++;
            }
        }
    }    
    return 0;
}
全部评论

相关推荐

贺兰星辰:不要漏个人信息,除了简历模板不太好以外你这个个人简介是不是太夸大了...
点赞 评论 收藏
分享
挣K存W养DOG:他真的很中意你,为什么不回他
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
11-21 19:05
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务