题目:hdu 1576 A/B
地址:http://acm.hdu.edu.cn/showproblem.php?pid=1576
思路:
1.题目要求 (A/B)%9973,那么我先求出 A = B*x;
2.由于题目给了n,B; n = A - A/9973 * 9973,因为(A/9973)为整数,所以令其为y;
3.将(1)(2)代替得:n = B*x - 9973*y;
4.由于gcd (B,9973) = 1,所以 B*_x+9973*_y = gcd(B,9973)=1; _x,_y必有整数解,传化成上式相似则:n = B*(_x*n) - 9973*-( _y*n);
5.可以看出x = _x*n;
那么我就可以先通过:B*_x+9973*_y = gcd(B,9973)=1运用欧几里德定理求出_x,_y;再求出x;
6.由于x可能为负数,所以将x变正 x = (x % 9973 +9973) % 9973
详细请看代码:
#include <stdio.h>
#define Mod 9973
__int64 Gcd (__int64 A, __int64 B, __int64 *x, __int64 *y)
{
__int64 temp,d;
if (B== 0)
{
* x =1;
* y = 0;
return A;
}
d=Gcd( B , A % B, x, y);
temp = *x;
*x = *y;
*y = temp - A/B*(*y);
return d;
}
int main(void)
{
__int64 B,n,T;
__int64 x,y;
scanf ("%I64d",&T);
while (T--)
{
scanf ("%I64d%I64d",&n,&B);
Gcd (B,Mod,&x,&y);
x=x*n;
x = (x%Mod + Mod)%Mod;
printf ("%I64d\n",x);
}
return 0;
}
地址:http://acm.hdu.edu.cn/showproblem.php?pid=2669
思路:1. 欧几里德公式:a*X + b*Y = gcd(a,b),如果gcd(a,b) != 1 输出sorry,否则输出X,Y
2. 但是X需要为最小正数。那么这一题还在考我们对X,Y的处理。
若X < 0 : X = X + B; Y = Y - A;
若X > 0 : X = X - B; Y = Y - A;
3. 注意输出格式 不是 X -Y,而是X Y;
详细请看代码:
#include <stdio.h>
int Gcd (int a, int b, int *x, int *y)
{
int d,tmp;
if (b == 0)
{
*x = 1;
*y = 0;
return a;
}
d = Gcd (b, a%b, x, y);
tmp = *x;
*x = *y;
*y = tmp - a/b*(*y);
return d;
}
int main(void)
{
int a,b,x,y,d;
while (scanf("%d%d",&a,&b) != EOF)
{
d =Gcd (a,b,&x,&y);
if (d != 1)
{
printf("sorry\n");
}
else
{
while (x>0) /*仔细看这里的处理方式*/
{
x -= b;
y +=a;
}
while (x<0)
{
x += b;
y -= a;
}
printf ("%d %d\n",x,y);
}
}
}
最后小结:这一次的题目都是数论-欧几里德算法的应用,用的非常不熟悉,数论题目不知道怎么去入手,需要多多练习。