码迷,mamicode.com
首页 > 其他好文 > 详细

方程的解

时间:2019-07-22 20:11:58      阅读:136      评论:0      收藏:0      [点我收藏+]

标签:typedef   scan   freopen   else   恶心   exgcd   include   mes   mat   

各种傻逼特判,判错一个就40

思路:

思路有两种

一,

首先求出来左右边界然后拿右边界减左边界,非常简单,按照解方程的方法求即可

代码(我没打出来一直40分,这里是nc的代码)

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;
ll T,a,b,c,x,y;
ll exgcd(ll a,ll b,ll &x,ll &y)
{
    if(b==0)
    {
        x=1;y=0;
        return a;
    }
    ll d=exgcd(b,a%b,x,y);
    ll tmp=x;
    x=y;
    y=tmp-a/b*y;
    return d;
}
int main()
{
    scanf("%lld",&T);
    while(T--)
    {
        scanf("%lld%lld%lld",&a,&b,&c);
        ll d=exgcd(a,b,x,y);
        ll l=floor(1.0*c/b*(-x)),r=ceil(1.0*c/a*y);
        ll k=r-l-1;
        if(a==0&&b==0)
        {
            if(c==0)
            {
                puts("ZenMeZheMeDuo");
                continue;
            }
            else
            {
                puts("0");
                continue;
            }
        }
        if((c%d))
        {
            puts("0");
            continue;
        }
        if(1LL*a*b<0)
        {
            puts("ZenMeZheMeDuo");
            continue;
        }
        if(a==0)
        {
            if(1LL*b*c>0) puts("ZenMeZheMeDuo");
            else puts("0");
            continue;
        }
        if(b==0)
        {
            if(1LL*a*c>0) puts("ZenMeZheMeDuo");
            else puts("0");
            continue;
        }
        if(k<0)
        {
            puts("0");
            continue;
        }
        if(k>65535) puts("ZenMeZheMeDuo");
        else printf("%lld\n",k);
    }
    return 0;
}

 

二,

求出来ymax 再求出来ymin 再/a

非常简单的思路(虽然我觉得第一个更简单)

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define A 100000
ll a,b,x,y,c,t;
ll exgcd(ll a,ll b,ll &x,ll &y)
{
    if(b==0)
    {
        x=1;y=0;
        return a;
    }
    ll c=exgcd(b,a%b,x,y);
    ll z=x;
    x=y;y=z-y*(a/b);
//    printf("x=%lld y=%lld\n",x,y);
    return c; 
}
int main()
{
//    freopen("data.in","r",stdin);
//    freopen("data.out","w",stdout);
    scanf("%lld",&t);
    while(t--)
    {
        scanf("%lld%lld%lld",&a,&b,&c);
//        printf("a=%lld b=%lld\n",a,b);
        x=0,y=0;
        if(a<0&&b<0) a=-a,b=-b,c=-c;        
        if(a==0)
        {
            if((b<=0&&c>=0)||(b>=0&&c<=0))
            {
                printf("0\n");
                continue;
            }
            else if(c%b){
                printf("0\n");
                continue;
            }
            else{printf("ZenMeZheMeDuo\n");continue;};
        }
        if(b==0)
        {
            if((a<=0&&c>=0)||(a>=0&&c<=0))
            {
                printf("0\n");
                continue;
            }
            else if(c%a){
                printf("0\n");
                continue;
            }
            else {printf("ZenMeZheMeDuo\n");continue;};
        }
        ll g=exgcd(a,b,x,y),ans=0;
        x*=c/g,y*=c/g;
//        printf("%lld %lld a=%lld b=%lld c=%lld\n",x,y,a,b,c);
        if(c%g){printf("0\n");continue;}
        if(a*b<0)
        {printf("ZenMeZheMeDuo\n");continue;}

        a/=g,b/=g,c/=g;x%=b;
        while(x<=0) x+=b;
        y=(c-a*x)/b;
        ll y2=y%a;
        while(y2<=0) y2+=a;
        ans=(y-y2)/a+1;
        if(y2>y) ans=0;
//        printf("y=%lld y2=%lld x=%lld c=%lld\n",y,y2,x,c);
        if(ans<=65535)
            printf("%lld\n",ans);
        else
            printf("ZenMeZheMeDuo\n");
    }
}

 

题目思路还是挺简单的就是一些恶心的特判

特判

首先$c \mod gcd!=0$时无解

然后$a,b$异号时无穷多解

$a$为$0$,$b$为$0$,$c$为$0$时无穷多解

$a$为$0$ $b$为$0$ $c$不为$0$ 无解

$ymax<ymin$无解

$a==0$ $  b,c$异号无解

$a==0$ $  b,c$同号无穷多解

$b==0$ $  a,c$异号无解

$b==0$ $  a,c$同号无穷多解

 

方程的解

标签:typedef   scan   freopen   else   恶心   exgcd   include   mes   mat   

原文地址:https://www.cnblogs.com/znsbc-13/p/11227871.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!