2019 Hang electric multi-school Contest5 1004 equation

Topic Link http://acm.hdu.edu.cn/showproblem.php?pid=6627

Question is intended to put the absolute value of n is given a linear equation, find x such that their sum is equal to c.

For | ax + b |, the absolute value considering removed, only two cases ax + b and -ax-b, depending on the value of x, i.e. x and b / a magnitude relation.

N equations and the range of x will be divided into intervals n + 1, then when the equation x takes a different range, the absolute value will change to remove a total of n + 1 case.

Discharge thinking according -a / b bit sequence, so that x takes each interval, n + 1 corresponding to a different one-linear equation, and then determines whether to directly solve the interval in the required range.

Note judgment about when some of the details.

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N=1e5+5;
const ll mod=998244353;
ll c;
int n;
struct node
{
    ll a,b;
};
bool cmp(node x,node y)
{
    return x.a*y.b<x.b*y.a;
}
bool cmp2(node x,node y)
{
    return x.a*y.b==x.b*y.a;
}
node f[N];
node ans[N];
int k;
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        memset(f,0,sizeof f);
        k=0;
        scanf("%d%lld",&n,&c);
        ll suma=0,sumb=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%lld%lld",&f[i].a,&f[i].b);
            if(f[i].a<0)
            {
                suma+=f[i].a;
                sumb+=f[i].b;
            }
            else
            {
                suma-=f[i].a;
                sumb-=f[i].b;
            }
        }//cout<<suma<<" "<<sumb<<endl;
        sort(f+1,f+1+n,cmp);
        int ff=0;
        for(int i=0;i<=n;i++)
        {
            suma+=2*f[i].a;
            sumb+=2*f[i].b;
            if(suma==0&&sumb==c)
            {
                ff=1;
                break;
            }
            ll x=c-sumb;
            ll y=suma;
            if(y<0)
            {
                y*=-1;
                x*=-1;
            }
            ll g=__gcd(abs(x),y);
            if((x*f[i+1].a<=-f[i+1].b*y)&&(f[i].a*x>=-f[i].b*y))
                ans[++k]={x/g,y/g};
        }
        if(ff)
        {
            printf("-1\n");
            continue;
        }
        k=unique(ans+1,ans+1+k,cmp2)-ans-1;
        printf("%d",k);
        for(int i=1;i<=k;i++)
        {
            printf(" %lld/%lld",ans[i].a,ans[i].b);
        }puts("");
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/liuquanxu/p/11305437.html