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
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 }