Description
克里特岛以野人群居而著称。岛上有排列成环行的M个山洞。这些山洞顺时针编号为1,2,…,M。岛上住着N个野人,一开始依次住在山洞C1,C2,…,CN中,以后每年,第i个野人会沿顺时针向前走Pi个洞住下来。每个野人i有一个寿命值Li,即生存的年数。下面四幅图描述了一个有6个山洞,住有三个野人的岛上前四年的情况。三个野人初始的洞穴编号依次为1,2,3;每年要走过的洞穴数依次为3,7,2;寿命值依次为4,3,1。
奇怪的是,虽然野人有很多,但没有任何两个野人在有生之年处在同一个山洞中,使得小岛一直保持和平与宁静,这让科学家们很是惊奇。他们想知道,至少有多少个山洞,才能维持岛上的和平呢?
Input
输入文件的第1行为一个整数N(1<=N<=15),即野人的数目。第2行到第N+1每行为三个整数Ci, Pi, Li (1<=Ci,Pi<=100, 0<=Li<=10^6 ),表示每个野人所住的初始洞穴编号,每年走过的洞穴数及寿命值。
Output
输出文件仅包含一个数M,即最少可能的山洞数。输入数据保证有解,且M不大于10^6。
分析
对于一个合法的m,必须满足的是n个人两两之间必须不能走重合。现在的问题是如何判定了。对于每两个人我们都可以算出他们走到同一个点的最短时间。
列出式子就是:ci+pi*x=cj+pj*x(mod m),再转化:(pi-pj)*x-my=cj-ci
那么我们已知pi-pj,m,cj-ci现在要求的是x。
这样就有了ax+by=c。这样一个式子已经很接近同余方程了,但不是。
同余方程是ax+by=gcd(a,b)。对此若上面的方程有解那么必有c%gcd(a,b)=0
这样可以转化成a’x+b’y=c’而a’=a/gcd(a,b),b’,c’类似。
此时再转化:a’x’+b’y’=1.那么求出x’后x=x’*c/gcd(a,b)。然而这里求出的x,y只是一组可行解,并不是最小解。
这里有:
a(x-b)+b(y+a)=gcd(a,b)
a(x-2b)+b(y+2a)=gcd(a,b)
。。。。。
a(x+2b)+b(y-2a)=gcd(a,b)
……..
所以我们只需把x%b’,就可以得到x>0且x最接近0的解了。(注意这里是b’)
找出了x的时候,再判断一下x是否<=min(l[i],l[j]),若是的话m便不合法,否则反之。
最后注明一下这里的每个式子转化时除的数必须是可以整除,所以我们才类似的用a/gcd(a,b)
var
n,i,k,j,ma,a,b,d,x,y,cc:longint;
c,p,l:array[1..15] of longint;
bz:boolean;
function max(l,r:longint):longint;
begin
if l<r then exit(r) else exit(l);
end;
function exgcd(a,b:longint;var x,y:longint):longint;
var t,er:longint;
begin
if b=0 then begin
x:=1;y:=0;exit(a);
end else begin
er:=exgcd(b,a mod b,x,y);
t:=x;
x:=y;
y:=t-(a div b)*y;
exit(er);
end;
end;
function min(l,r:longint):longint;
begin
if l<r then exit(l) else exit(r);
end;
begin
readln(n);
for i:=1 to n do begin
readln(c[i],p[i],l[i]);
ma:=max(ma,c[i]);
end;
for k:=ma to 1000000 do begin
bz:=true;
for i:=1 to n-1 do begin
for j:=i+1 to n do begin
a:=p[i]-p[j];b:=k;cc:=c[j]-c[i];
if (k=6)and(i=2) then
n:=n;
d:=exgcd(a,b,x,y);
if cc mod d<>0 then continue;
x:=(x*cc div d) mod (b div d);
if x<0 then x:=x+abs(b div d);
if x<=min(l[i],l[j]) then begin
bz:=false;break;
end;
end;
if not bz then break;
end;
if bz then break;
end;
writeln(k);
close(input);close(output);
end.