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>
【样例说明】
该样例对应于题目描述中的例子。