bzoj1407 [Noi2002]Savage——擴展歐幾裏得
阿新 • • 發佈:2018-07-01
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——擴展歐幾裏得