bzoj1407 [Noi2002]Savage

Description

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。

Sample Input

3
1 3 4
2 7 3
3 2 1

Sample Output

6
//该样例对应于题目描述中的例子。

正解:$exgcd$。

直接对于所有答案暴力枚举,用$exgcd$判断合法性就行了。

 1 #include <bits/stdc++.h>
 2 #define il inline
 3 #define RG register
 4 
 5 using namespace std;
 6 
 7 int c[20],p[20],l[20],n,M;
 8 
 9 il int gi(){
10   RG int x=0,q=1; RG char ch=getchar();
11   while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
12   if (ch=='-') q=-1,ch=getchar();
13   while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
14   return q*x;
15 }
16 
17 il int exgcd(RG int a,RG int b,RG int &x,RG int &y){
18   if (!b){ x=1,y=0; return a; }
19   RG int r=exgcd(b,a%b,y,x); y-=a/b*x; return r;
20 }
21 
22 il int check(RG int i,RG int j,RG int M){
23   RG int a=(p[i]-p[j])%M,b=(c[j]-c[i])%M;
24   if (a<0) a+=M; if (b<0) b+=M;
25   RG int x,y,G=exgcd(a,M,x,y);
26   if (b%G) return 0; M/=G;
27   while (x<0) x+=M;
28   x=1LL*x*(b/G)%M; if (x<=0) x+=M;
29   return x<=min(l[i],l[j]);
30 }
31 
32 int main(){
33 #ifndef ONLINE_JUDGE
34   freopen("savage.in","r",stdin);
35   freopen("savage.out","w",stdout);
36 #endif
37   n=gi();
38   for (RG int i=1;i<=n;++i)
39     c[i]=gi(),p[i]=gi(),l[i]=gi(),M=max(M,c[i]);
40   for (;;++M){
41     RG int fg=1;
42     for (RG int i=1;i<n;++i){
43       for (RG int j=i+1;j<=n;++j)
44     if (check(i,j,M)){ fg=0; break; }
45       if (!fg) break;
46     }
47     if (fg) break;
48   }
49   cout<<M; return 0;
50 }
原文地址:https://www.cnblogs.com/wfj2048/p/7603437.html