1. 程式人生 > >BZOJ-1407: [Noi2002]Savage (擴展歐幾裏得)

BZOJ-1407: [Noi2002]Savage (擴展歐幾裏得)

source noi spa esp n) scanf 技術 int 線性

1407: [Noi2002]Savage

Time Limit: 5 Sec Memory Limit: 64 MB
Submit: 2276 Solved: 1019
[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

Sample Output

6
//該樣例對應於題目描述中的例子。

HINT

Source

鳴謝劉汝佳先生授權使用

這題挺水的qwq

一開始是想著枚舉任意兩個人然後把可能的天數全部去掉,最後枚舉m

然鵝孬孬說不能這麽寫??? 不知什麽情況qwq 於是就先枚舉m,在判斷m可不可行

C1+P1*x=C2+P2*x+M*y => (P1-P2)*x+(-M)*y=C2-C1

可惜laj忘了模線性方程怎麽解了 _(:зゝ∠)_

 1 #include "
bits/stdc++.h" 2 using namespace std; 3 const int MAX=25; 4 int n,m,C[MAX],P[MAX],L[MAX]; 5 int exgcd(int a,int b,int &x,int &y){ 6 if (b==0) return x=1,y=0,a; 7 int d=exgcd(b,a%b,x,y); 8 int t=x; x=y,y=t-a/b*y; 9 return d; 10 } 11 int main(){ 12 freopen ("gcd.in","r",stdin);freopen ("
gcd.out","w",stdout); 13 int i,j,a,b,c,d,e,f,x,y; 14 scanf("%d",&n); 15 for (i=1;i<=n;i++) scanf("%d%d%d",C+i,P+i,L+i),m=max(m,C[i]); 16 for (;m<=1e6;m++){ 17 bool flag=true; 18 for (i=1;i<=n;i++){ 19 for (j=i+1;j<=n;j++){ 20 a=P[i]-P[j],b=m,c=C[j]-C[i]; 21 d=exgcd(a,b,x,y); 22 if ((c%d)!=0) continue; 23 x=x*c/d,x=x%(m/d); 24 if (x<0) x+=abs(m/d); 25 if (x<=L[i] && x<=L[j]) {flag=false;goto away;} 26 } 27 } 28 away:if (flag) return printf("%d",m),0; 29 } 30 }

BZOJ-1407: [Noi2002]Savage (擴展歐幾裏得)