1407: [Noi2002]Savage
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1909 Solved: 859
[ Submit][ Status][ Discuss]
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
【分析】
参见 http://www.cnblogs.com/SilverNebula/p/5660192.html
【代码】
#include<iostream>
#include<cstring>
#include<cstdio>
#define inf 1e9+7
#define ll long long
#define fo(i,j,k) for(i=j;i<=k;i++)
using namespace std;
const int mxn=20;
int n,m;
int C[mxn],p[mxn],l[mxn];
inline int gcd(int x,int y) {return x%y==0?y:gcd(y,x%y);}
inline void exgcd(int a,int b,int &x,int &y)
{
if(!b) {x=1,y=0;return;}
exgcd(b,a%b,y,x);
y-=a/b*x;
}
inline bool ok()
{
int i,j,x,y;
fo(i,1,n)
fo(j,i+1,n)
{
int a=p[i]-p[j],b=m,c=C[j]-C[i];
int tmp=gcd(a,b);
if(c%tmp!=0) continue;
a/=tmp,b/=tmp,c/=tmp;
if(b<0) b=-b;
exgcd(a,b,x,y);
x=((x*c%b)+b)%b;
if(!x) x+=b;
if(x<=min(l[i],l[j])) return 0;
}
return 1;
}
int main()
{
int i,j;
scanf("%d",&n);
fo(i,1,n)
{
scanf("%d%d%d",&C[i],&p[i],&l[i]);
m=max(m,C[i]);
}m--;
while(++m)
if(ok())
{
printf("%d\n",m);
return 0;
}
}