您的位置:首页 > 其它

Bzoj1407 Savage

2016-07-11 14:40 225 查看

 

Description

Input

第1行为一个整数N(1<=N<=15),即 野人的数目。第2行到第N+1每行为三个整数Ci, Pi, Li (1<=Ci,Pi<=100, 0<=Li<=106 ),表示每个野人所住的初始洞穴编号,每年走过的洞穴数及寿命值。

Output

仅包含一个数M,即最少可能的山洞数。输入数据保证有解,且M不大于106。

Sample Input

3
1 3 4
2 7 3
3 2 1

Sample Output

6

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

 

 

考虑两个野人i、j的情况:设他们在x年后相遇,则得到该式: P[i]*x+C[i]=P[j]*x+C[j](mod M)

化为同余方程: (P[i]-P[j])*x+k*M=C[j]-C[i]

按照题目要求,我们需要找到一个M,使得上式无解或者x>min(C[i],C[j])  (在野人有生之年没有相遇)

问题扩展到所有野人,由于数据范围很小,可以直接枚举M,判断是否所有野人之间都满足要求。

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int mxn=1000;
int c[mxn],le[mxn],p[mxn];
int n;
int m;
int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
int exgcd(int a,int b,int &x,int &y){
if(b==0){
x=1;
y=0;
return a;
}
exgcd(b,a%b,x,y);
int t=x;
x=y;
y=t-(a/b)*y;
}
bool judge(int m){

int i,j;
int t,x,y;
for(i=1;i<n;i++){
for(j=i+1;j<=n;j++){
int a=p[i]-p[j];
int b=m;
int c1=c[j]-c[i];
t=gcd(a,b);

if(c1%t==0){
a/=t;b/=t;c1/=t;
exgcd(a,b,x,y);
b=abs(b);
x=((c1*x)%b+b)%b;
if(!x)x+=b;
if(x<=min(le[i],le[j]))return 0;
}
}
}
return 1;
}
int main(){
scanf("%d",&n);
int i,j;
m=0;
for(i=1;i<=n;i++){
scanf("%d%d%d",&c[i],&p[i],&le[i]);
if(c[i]>m)m=c[i];
}
for(i=m;i;i++){
if(judge(i)){
printf("%d\n",i);
break;
}
}
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: