• 2019杭电多校Contest5 1004 equation


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

    题意是给出n个套上绝对值的一元一次方程,求x使得他们的和等于c。

    对于|ax+b|,考虑去掉绝对值,只有两种情况 ax+b 和 -ax-b,取决于x的取值,也就是 x 与 b/a 的大小关系。

    然后n个方程就会把x的范围划分为n+1个区间,然后当x取不同的范围,去掉绝对值的方程就会发生变化,一共有n+1种情况。

    想着按照 -a/b 排一下序,这样x取每一个区间,对应不同的n+1个一元一次方程,直接求解然后判断是否在要求的区间范围内即可。

    注意一下判断的时候一些细节。

    #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
    ");
                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;
    }
  • 相关阅读:
    68
    56
    Django manager 命令笔记
    Django 执行 manage 命令方式
    Django 连接 Mysql (8.0.16) 失败
    Python django 安装 mysqlclient 失败
    H.264 SODB RBSP EBSP的区别
    FFmpeg—— Bitstream Filters 作用
    MySQL 远程连接问题 (Windows Server)
    MySQL 笔记
  • 原文地址:https://www.cnblogs.com/liuquanxu/p/11305437.html
Copyright © 2020-2023  润新知