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
//该样例对应于题目描述中的例子。
//该样例对应于题目描述中的例子。
HINT
Source
正解:搜索+扩展欧几里得
解题报告:
今天上午考试的T2,一上来一看,这不是板子题吗?然后就没有然后了...
考虑枚举一共有多少个山洞,每次对于当前的山洞个数,两两check一下,看一下是否会冲突。check的方式很简单,就是直接解他们相遇的不定方程,很容易根据他们的信息得到一个方程,看一下最小正整数解是否在他们的寿命范围内。可以发现这样做的理论复杂度是TLE的,但是很显然我们每次check复杂度远远不到n^2,所以不会T。
1 //It is made by jump~ 2 #include <iostream> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cstdio> 6 #include <cmath> 7 #include <algorithm> 8 #include <ctime> 9 #include <vector> 10 #include <queue> 11 #include <map> 12 #include <set> 13 using namespace std; 14 typedef long long LL; 15 const int inf = (1<<30); 16 const int MAXN = 15+30; 17 int n,minl,a,b,c; 18 int ini[MAXN],p[MAXN],L[MAXN]; 19 //c[i]+p[i]*x=c[j]+p[j]*x-now*y ==> (c[i]-c[j])*x+now*y=c[j]-c[i] 20 21 inline int getint() 22 { 23 int w=0,q=0; char c=getchar(); 24 while((c<'0' || c>'9') && c!='-') c=getchar(); if(c=='-') q=1,c=getchar(); 25 while (c>='0' && c<='9') w=w*10+c-'0', c=getchar(); return q ? -w : w; 26 } 27 28 inline int gcd(int x,int y){ 29 if(y==0) return x; 30 return gcd(y,x%y); 31 } 32 33 inline void extend_gcd(int a,int b,int &x,int &y){ 34 if(b==0) { 35 x=1; 36 y=0; 37 return ; 38 } 39 extend_gcd(b,a%b,x,y); 40 int lin=x; x=y; 41 y=lin-(a/b)*y; 42 } 43 44 inline void check(int now){//两两检查合法性 45 int gong,x,y; 46 for(int i=1;i<n;i++) 47 for(int j=i+1;j<=n;j++) { 48 a=(p[i]-p[j]); b=now; c=(ini[j]-ini[i]); gong=gcd(a,b); 49 if(c%gong!=0) continue; //无解 50 a=a/gong; b=b/gong; c=c/gong; 51 extend_gcd(a,b,x,y); 52 if(b<0) b=-b; 53 x=x*c; x%=b; x+=b; x+=b; x%=b; 54 if(x<=L[i] && x<=L[j]) return ; 55 } 56 printf("%d",now); 57 exit(0); 58 } 59 60 inline void work(){ 61 n=getint(); for(int i=1;i<=n;i++) ini[i]=getint(),p[i]=getint(),L[i]=getint(); 62 for(int i=1;i<=n;i++) minl=max(minl,ini[i]);//至少是ini[i]的最大值 63 for(;;minl++) check(minl); 64 } 65 66 int main() 67 { 68 work(); 69 return 0; 70 }
本文作者:ljh2000
作者博客:http://www.cnblogs.com/ljh2000-jump/
转载请注明出处,侵权必究,保留最终解释权!