• 洛谷 P5656 【模板】二元一次不定方程 (exgcd)


    传送门


    解题思路

    先转化为:
    ax+by=gcd(a,b)
    exgcd板子,求出一组特解(x_0),(y_0)后,我们发现,可以将
    (x_0+frac{kb}{gcd(a,b)})
    (y_0-frac{ka}{gcd(a,b)})
    所以可以得出,x的最小正整数解为(((x-1)\%(b/gcd)+b/gcd)\%(b/gcd)+1)
    注意因为要求正整数而不是整数,所以x一开始要减1后面要加1。
    因为abc都大于零,所以只需看x取最小正整数解时y的正负就可以判断方程是否有正整数解,看y同理。

    AC代码

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<ctime>
    using namespace std;
    int T;
    long long x,y;
    int exgcd(long long a,long long b){
    	if(b==0){
    		x=1;
    		y=0;
    		return a;
    	}
    	int gcd=exgcd(b,a%b);
    	swap(x,y);
    	y=y-(a/b)*x;
    	return gcd;
    }
    int main(){
    	cin>>T;
    	while(T--){
    		long long a,b,c;
    		scanf("%lld%lld%lld",&a,&b,&c);
    		int gcd=exgcd(a,b);
    		if(c%gcd!=0){
    			printf("-1
    ");
    			continue;
    		}
    		x*=c/gcd;
    		y*=c/gcd;
    		long long minx=((x-1)%(b/gcd)+b/gcd)%(b/gcd)+1,maxy=(c-minx*a)/b;
    		long long miny=((y-1)%(a/gcd)+a/gcd)%(a/gcd)+1,maxx=(c-miny*b)/a;
    		if(maxy<=0){
    			printf("%lld %lld
    ",minx,miny);
    			continue;
    		}
    		printf("%lld %lld %lld %lld %lld
    ",(maxx-minx)/(b/gcd)+1,minx,miny,maxx,maxy);
    	}
    	return 0;
    }
    

    注意开long long。

  • 相关阅读:
    Tree(未解决。。。)
    Fractal(递归,好题)
    Scrambled Polygon(凸多边形,斜率)
    ZYB's Game(博弈)
    Dancing Stars on Me(判断正多边形)
    Hidden String(深搜)
    1043
    TEX Quotes(字符串,水)
    Candy Sharing Game(模拟搜索)
    hpu校赛--雪人的高度(离散化线段树)
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/14768833.html
Copyright © 2020-2023  润新知