P2421 [NOI2002]荒島野人

題目背景

原 A-B數對(加強版)參見P1102c++

題目描述

克里特島以野人羣居而著稱。島上有排列成環行的M個山洞。這些山洞順時針編號爲1,2,…,M。島上住着N個野人,一開始依次住在山洞C1,C2,…,CN中,之後每一年,第i個野人會沿順時針向前走Pi個洞住下來。spa

每一個野人i有一個壽命值Li,即生存的年數。code

下面四幅圖描述了一個有6個山洞,住有三個野人的島上前四年的狀況。三個野人初始的洞穴編號依次爲1,2,3;每一年要走過的洞穴數依次爲3,7,2;壽命值依次爲4,3,1。blog

奇怪的是,雖然野人有不少,但沒有任何兩個野人在有生之年處在同一個山洞中,使得小島一直保持和平與寧靜,這讓科學家們非常驚奇。他們想知道,至少有多少個山洞,才能維持島上的和平呢?it

輸入格式

第1行爲一個整數N(1<=N<=15),即野人的數目。class

第2行到第N+1每行爲三個整數Ci, Pi, Li (1<=Ci,Pi<=100, 0<=Li<=106 ),表示每一個野人所住的初始洞穴編號,每一年走過的洞穴數及壽命值。循環

輸出格式

僅包含一個數M,即最少可能的山洞數。輸入數據保證有解,且M不大於10^6。gc

輸入輸出樣例

輸入 #1

3
1 3 4
2 7 3
3 2 1

輸出 #1

6

解題思路

  首先,對於第i個野人和第j個野人,咱們都但願Ci+k*Pi≡Cj+k*Pj(mod ans)的k>他們兩個壽命最短的一個,由於就算遇到了,也死了.........im

  而後就有k*(Pi-Pj)+m*ans=Cj-Ci,就是裸的exgcd了................數據

題解

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int c[101],p[101],l[101];
 4 int x,y;
 5 int exgcd(int a,int b)
 6 {
 7     if(b==0)
 8     {
 9         x=1;
10         y=0;
11         return a;
12     }
13     int g=exgcd(b,a%b); 
14     int z=x;
15     x=y;
16     y=z-(a/b)*y;
17     return g;
18 }
19 int main()
20 {
21     int n,maxc=0;
22     scanf("%d",&n);
23     for(int i=1;i<=n;i++)
24     {
25         scanf("%d%d%d",&c[i],&p[i],&l[i]);
26         maxc=max(maxc,c[i]);//確定從最大的編號開始枚舉 
27     }
28     for(int ans=maxc;;ans++)//枚舉山洞的數量 
29     {
30         bool flag=0;
31         for(int i=1;i<=n;i++)
32         {
33             for(int j=i+1;j<=n;j++)//雙層循環,每兩個野人一個同餘方程 
34             {
35                 int k=p[i]-p[j];
36                 k=(k%ans+ans)%ans;
37                 int g=exgcd(k,ans);//最大公約數 
38                 if((c[j]-c[i])%g)//若是這個解不合法 
39                     continue;//說明永遠也碰不着 
40                 x*=((c[j]-c[i])/g);//求要追上的年數 
41                 int mod=ans/g;
42                 x=(x%mod+mod)%mod;
43                 if(x<=min(l[i],l[j]))//若是追上了 
44                 {
45                     flag=1;//洞穴數量不合法標記退出 
46                     break;
47                 }
48             }
49             if(flag)break;
50         }
51         if(flag)continue;
52         printf("%d",ans);//合法了就輸出 
53         return 0;
54     }
55 }
相關文章
相關標籤/搜索