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&lt;=N&lt;=15),即野人的數目。第2行到第N+1每行爲三個整數Ci, Pi, Li (1&lt;=Ci,Pi&lt;=100, 0&lt;=Li&lt;=106 ),表示每個野人所住的初始洞穴編號,每年走過的洞穴數及壽命值。
【輸出文件】

輸出文件僅包含一個數M,即最少可能的山洞數。輸入數據保證有解,且M不大於106。
【樣例輸入】
<pre>3
1 3 4
2 7 3
3 2 1</pre>
【樣例輸出】
<pre>6</pre>
【樣例說明】

該樣例對應於題目描述中的例子。

相關日誌