1. 程式人生 > >bzoj1407 [Noi2002]Savage——擴展歐幾裏得

bzoj1407 [Noi2002]Savage——擴展歐幾裏得

for return oid main exgcd namespace continue AI php

題目:https://www.lydsy.com/JudgeOnline/problem.php?id=1407

看到一定有解,而且小於10^6,所以可以枚舉;

判斷一個解是否可行,就兩兩判斷野人 i , j 能否滿足在壽命內不相遇;

也就是 T*pi + ci ≡ T*pj + cj (mod m)

變成 ( pi - pj )*T + km = cj - ci

用擴展歐幾裏得解這個方程,得到T若大於兩人中較小的壽命或無解則可行。

代碼如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include
<cmath> using namespace std; int n,m,c[20],p[20],l[20]; int gcd(int a,int b){return (a%b==0)?b:gcd(b,a%b);} void exgcd(int a,int b,int &x,int &y) { if(b==0) { x=1; y=0; return; } exgcd(b,a%b,x,y); int t=x; x=y; y=t-(a/b)*y; } bool ck(int m) { for(int i=1
;i<n;i++) for(int j=i+1;j<=n;j++) { int a=p[i]-p[j],b=m,cc=c[j]-c[i]; int g=gcd(a,b); // if(cc%g)return 0; if(cc%g)continue;//無解也滿足 a/=g; b/=g; cc/=g; int x,y; // b=abs(b); if(b<0)b=-b; exgcd(a,b,x,y); x
=((x*cc)%b+b)%b;//先%b! // x=(x*cc+b)%b; 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]),m=max(m,c[i]); for(int i=m;i<=1e6;i++) if(ck(i)) { printf("%d",i); return 0; } }

bzoj1407 [Noi2002]Savage——擴展歐幾裏得