NOI 2002 荒島野人
這是一個數論問題。首先說給定一個M,判斷M是否可行。假設兩個野人爲i和j,設兩個人在第x年相遇,則C[i] + x P[i] === C[j] + x P[j] ( Mod M ),x的最小非負解應至少大於L[i]和L[j]的任意一個(相遇時已至少有一個人死亡),或者無解(兩人不可能相遇)。對於每對(i,j)都進行檢查, 如果所有人都不能相遇,則說明M是一個可行解。對於M應從小到大枚舉,這樣首次滿足條件的M就是解了。
上述式子轉化爲標準線性同餘方程就是 (P[i]-P[j]) * x === C[j] - C[j] ( Mod M ),應保證P[i]-P[j]不爲負數。要注意M最小值應不小於任意一個C[i]。
/*
* Problem: NOI2002 savage
* Author: Guo Jiabao
* Time: 2009.5.20 22:36
* State: Solved
* Memo: 線性同餘方程
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
const int MAXN=16;
using namespace std;
int C[MAXN],P[MAXN],L[MAXN],N,M,S;
void init()
{
freopen("savage.in","r",stdin);
freopen("savage.out","w",stdout);
scanf("%d",&N);
S=N;
for (int i=1;i<=N;i++)
{
scanf("%d%d%d",&C[i],&P[i],&L[i]);
if (C[i] > S)
S=C[i];
}
}
int extend_gcd(int a,int b,int &x,int &y)
{
if (!b)
{
x=1;y=0;
return a;
}
else
{
int t,d;
d=extend_gcd(b,a%b,x,y);
t=x; x=y; y=t-(a/b)*y;
return d;
}
}
int mod_eq(int a,int b,int n)
{
int d,x,y;
d = extend_gcd(a,n,x,y);
if (b%d) return -1;
x = x * b / d % (n / d);
x = ( x + n / d ) % ( n / d );
return x;
}
bool legal()
{
int i,j,x,a,b;
for (i=1;i<N;i++)
{
for (j=i+1;j<=N;j++)
{
a=P[j]-P[i];b=C[i]-C[j];
if (a<0 && b<0)
a=-a,b=-b;
if (a<0 && b>0)
x=a,a=b,b=x;
x=mod_eq(a,b,M);
if (!(x==-1 || x>L[i] || x>L[j]))
return false;
}
}
return true;
}
void solve()
{
for (M=S;!legal();M++);
printf("%dn",M);
}
int main()
{
init();
solve();
return 0;
}
<h2><span class="mw-headline">荒島野人 </span></h2>
【問題描述】
克里特島以野人羣居而著稱。島上有排列成環行的M個山洞。這些山洞順時針編號爲1,2,…,M。島上住着N個野人,一開始依次住在山洞 C1,C2,…,CN中,以後每年,第i個野人會沿順時針向前走Pi個洞住下來。每個野人i有一個壽命值Li,即生存的年數。下面四幅圖描述了一個有6個 山洞,住有三個野人的島上前四年的情況。三個野人初始的洞穴編號依次爲1,2,3;每年要走過的洞穴數依次爲3,7,2;壽命值依次爲4,3,1。
<a class="image" title="Image:Savage1.gif" href="http://www.ruvtex.cn/wiki/Image:Savage1.gif"><img src="http://www.ruvtex.cn/mw/images/8/87/Savage1.gif" alt="Image:Savage1.gif" width="246" height="138" /></a>
<a class="image" title="Image:Savage2.gif" href="http://www.ruvtex.cn/wiki/Image:Savage2.gif"><img src="http://www.ruvtex.cn/mw/images/e/e8/Savage2.gif" alt="Image:Savage2.gif" width="238" height="103" /></a>
<a class="image" title="Image:Savage3.gif" href="http://www.ruvtex.cn/wiki/Image:Savage3.gif"><img src="http://www.ruvtex.cn/mw/images/4/45/Savage3.gif" alt="Image:Savage3.gif" width="230" height="131" /></a>
<a class="image" title="Image:Savage4.gif" href="http://www.ruvtex.cn/wiki/Image:Savage4.gif"><img src="http://www.ruvtex.cn/mw/images/2/21/Savage4.gif" alt="Image:Savage4.gif" width="238" height="110" /></a>
奇怪的是,雖然野人有很多,但沒有任何兩個野人在有生之年處在同一個山洞中,使得小島一直保持和平與寧靜,這讓科學家們很是驚奇。他們想知道,至少有多少個山洞,才能維持島上的和平呢?
【輸入文件】
輸入文件的第1行爲一個整數N(1<=N<=15),即野人的數目。第2行到第N+1每行爲三個整數Ci, Pi, Li (1<=Ci,Pi<=100, 0<=Li<=106 ),表示每個野人所住的初始洞穴編號,每年走過的洞穴數及壽命值。
【輸出文件】
輸出文件僅包含一個數M,即最少可能的山洞數。輸入數據保證有解,且M不大於106。
【樣例輸入】
<pre>3
1 3 4
2 7 3
3 2 1</pre>
【樣例輸出】
<pre>6</pre>
【樣例說明】
該樣例對應於題目描述中的例子。