Title Link: http://www.lydsy.com/JudgeOnline/problem.php?id=1407
Test instructions
There are N Savage, savage each live in the C[i] a cave (cave into a ring), every year to go forward P[i] a cave, to this cave to live down.
Each savage's life expectancy is l[i], ask at least how many caves, can let Savage in Lifetime never live in the same cave.
Exercises
Would not have expanded Euclidean and congruence equations, here as far as possible to write in detail from this topic learned.
I originally from the Internet to look at various types of the problem and then hit, because do not understand and some of the wrong, resulting in a long time.
The following is my problem, if there are errors, please point out.
The number of caves is M.
First of all, for n=2, if meet, then have congruence equation c[i]+x*p[i] = c[j]+x*p[j] (mod m)
To be moved: (P[i]-p[j]) *x=c[j]-c[i] (mod m)
ie: (P[i]-p[j]) *x + m*y = c[j]-c[i]
Because P[i]-p[j], M, c[j]-c[i] are known, the equation is equivalent to A*x+b*y=c, which can be solved by expanding Euclid.
If the equation is no solution, or x is less than l[i] and X is less than l[j] (attention is and the relationship, because a dead one alive also cannot meet), then will not meet.
So, since n<=15, you can enumerate m from Max (C[i]) (since savages are not in the same cave at first, Max (C[i]) must be greater than or equal to N), 22 matches, and if none of them meet, the current m-value is the smallest integer solution.
Related: Indefinite equation a*x + B*y = C with extended Euclidean algorithm:
Recommend a good blog post: http://www.cnblogs.com/Rinyo/archive/2012/11/25/2787419.html
If c is not a multiple of gcd (A, B), then the equation has no solution.
Prove:
Set G=GCD (A, B), then A=a ' g,b=b ' g
Ax+by=c can be converted to g (a ' x+b ' Y) =c
Since G, (a ' x+b ' Y) and C are integers, C is necessarily a multiple of G.
To expand Euclid:
int exgcd (int a,int b) {if (b = = 0) {x=1,y=0; return A;} int t = EXGCD (b,a%b,x,y); int x0 = x, y0 = Y;x = y0; y = x0-(A/b) *y0;return t;}
Prove:
Ax + by = gcd (A, B)
BX ' + (a%b) y ' =gcd (b,a%b)
Because GCD (A, b) = gcd (b,a%b)
So ax+by = bx ' + (a%b) y '
Substituting a%b = a-⌊ A/b⌋*b (⌊⌋ is the down-rounded symbol)
Ax + by = BX ' + (a-⌊a/b⌋*b) y '
ax + by = Ay ' + b (x '-⌊a/b⌋y ')
So: x = y ' y = X '-⌊a/b⌋*y '
The answer can be reached by backtracking.
The x and y obtained here are a set of feasible solutions that can be used
x = X ' + k*b
y = y ' + k*b
Find the smallest integer solution.
Note: ax + by = c is a solution that C is a multiple of gcd (A, B).
Method One:
Both sides of the equation are divided by g
A ' =a/g B ' =b/g C ' =c/g
Get a ' x+b ' y=c '
Solving a ' x ' +b ' y ' =1 by expanding Euclidean algorithm
Then x = X ' *c ' y = y ' *c '
At this point, when the formula is used to find the smallest integer solution, the addition and subtraction should be B '
Method Two:
We can directly find out ax ' + by ' =1
Then x = X ' *c/g y = y ' * c/g
At this point, it should be noted that in the general formula to find the smallest integer solution plus minus should still be b/g. Note )
The code is as follows:
1#include <cstdio>2#include <cstdlib>3#include <cstring>4#include <iostream>5 using namespacestd;6 7 Const intn= -, m=1000010;8 intN;9 intCc[n],p[n],l[n];Ten One intMaxxintXintY) {returnX>y?x:y;} A intMinn (intXintY) {returnX<y?x:y;} - intMyabs (intx) {returnX>0? x:-x;} - the intgcdintAintb) - { - if(b==0)returnA; - returnGCD (b,a%b); + } - + voidEXGCD (intAintBint&x,int&y) A { at if(b==0) {x=1, y=0;return ;} -EXGCD (b,a%b,x,y); - intx0=x,y0=y; -X=y0;y=x0-(A/b) *y0; - return ; - } in - BOOLCheckintm) to { + for(intI=1; i<=n-1; i++) - for(intj=i+1; j<=n;j++) the { * inta=p[i]-P[j]; $ intb=m;Panax Notoginseng intc=cc[j]-Cc[i]; - the intg=gcd (A, b); + if(c%g)Continue; Aa/=g;b/=g;c/=g;//b may become negative here the intx, y; + EXGCD (a,b,x,y); -x=x*c;y=y*C; $ while(x>0) x-=Myabs (b); $ while(x<=0) x+=Myabs (b); - if(X<=minn (L[i],l[j]))return 0;// - } the return 1; - }Wuyi the intMain () - { Wuscanf"%d",&n); - intmx=N; About for(intI=1; i<=n;i++) $ { -scanf"%d%d%d",&cc[i],&p[i],&L[i]); -mx=Maxx (Mx,cc[i]); - } A for(inti=mx;i<=m;i++) + { the if(check (i)) {printf ("%d\n", i); Break;} - } $ return 0; the}
View Code
"lydsy1407" expands Euclid to solve indefinite equation + congruence equation