HDU 1576 A/B (两种解法)

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

分析:等式枚举法,由题意可得:A=n+k*9973(A/B)%9973=x(A\setminus B ) mod 9973 = x,代入 A,  ((n+k*9973)/B)mod9973=x  得:n+k*9973=B*k2*9973+B*x,把变量 k, k2 合在一起得: B*x-n=(k-B*k2)*9973 ;即满足 B*x-n9973 倍数,因为 x<9973,所以解时唯一的。

         使用扩展欧几里德算法 费马小定理 来求解,涉及到有关逆元的知识这里就不详细叙述了。

代码如下:

       方法一(等式枚举):

#include <bits/stdc++.h>
using namespace std;

int main(void)
{
    int t;
    cin >> t;
    
    while(t--)
    {
        long long a , b, n;
        cin >> n >> b;
        for(int i = 1;i <= 9972; i++)
        {
            long long x;
             x = b * i - n;
             if(x % 9973 == 0)
            {
                cout << i << endl;
                break;
            }
        } 
	}
    
    return 0;
 }

       方法二(求逆元法):

#include <bits/stdc++.h>
using namespace std;

// 费马小定理
/*long long quickpow(long long a, long long b) {                         
	if (b < 0) return 0;
	long long ret = 1;
	a %= 9973;
	
	while (b) {
		if (b & 1) ret = (ret * a) % 9973;
		b >>= 1;
		a = (a * a) % 9973;
	}
	return ret;
}*/

int x, y;
int exgcd(int a, int b) {            // 扩展欧几里德算法
	int t;
	if (b == 0) // 推理, 终止条件1
	{
		x = 1;
		y = 0;
		return a;
	} 
	else {
		exgcd(b, a%b);
		t = x;
		x = y;
		y = t - (a/b) * y;
	}
}
int main(void)
{
    int t;
    cin >> t;
    
    while(t--)
    {
        long long a , b, n;
        cin >> n >> b;
        
		//int x = quickpow(b, 9973 - 2);
		exgcd(b, 9973);
		if (x < 0) x += 9973;
		x *= n;
		 
        cout << x % 9973 << endl;
    }
    
    return 0;
 }

猜你喜欢

转载自blog.csdn.net/laugh12321/article/details/81191686