1. 程式人生 > >[Noi2002]Savage

[Noi2002]Savage

ostream code 人的 一個數 rip 技術分享 tput src i++

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

題解:   看到答案小於1000000,就可以枚舉答案,然後,對於每兩個人,另他們在x年相遇,那麽第i個人就會走到(Ci+x*pi)%ans,如果i,j到一個洞穴就有,(Ci+x*pi)和(Cj+x*pj)和ans同余。
  轉化一下就變成了(pi-pj)*x和Cj-Ci同余,這就變成了一個解同余方程的解的問題,要求最小解x比他們兩個人的壽命都要打。   然而我都忘了怎麽用exgcd求同余方程的解了,還是現學的,註:exgcd,對於兩個系數為負的情況也試用。 代碼:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#define
ll long long using namespace std; int c[20],p[20],l[20],n,maxx=0; ll exgcd(ll a,ll b,ll &x,ll &y){ if(b==0){ x=1,y=0;return a; } ll z=exgcd(b,a%b,x,y),t=x; x=y,y=t-a/b*y;return z; } bool check(int m){ for(int i=1;i<n;i++) for(int j=i+1;j<=n;j++){ ll A
=p[i]-p[j],C=c[j]-c[i],x,y,t; t=exgcd(A,m,x,y); if(C%t) continue; x=x*C/t;x=x%(m/t); if(x<0) x+=abs(m/t); if(x<=min(l[i],l[j])) return 0; } return 1; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d%d%d",&c[i],&p[i],&l[i]),maxx=max(maxx,c[i]); for(int i=maxx;i<=1000000;i++){ if(check(i)){ printf("%d",i); return 0; } } return 0; }

[Noi2002]Savage