[BZOJ1407][NOI2002]Savage(扩欧)

来源:互联网 发布:时序数据分类基本原理 编辑:程序博客网 时间:2024/05/29 12:55

题目描述

传送门

题解

从初始山洞编号的最大值来枚举山洞的个数m。
枚举之后每次两两扩欧:
Ci+xPiCj+xPj(modm)
满足题意的条件是无解或最小的x大于某一个野人的寿命。

代码

#include<iostream>#include<cstring>#include<cstdio>#include<cstdlib>using namespace std;const int max_n=20;int C[max_n],P[max_n],L[max_n];int Max,n,a,b,c,x,y;inline int gcd(int a,int b){    if (!b) return a;    else return gcd(b,a%b);}inline void exgcd(int a,int b,int &x,int &y){    if (!b) x=1,y=0;    else exgcd(b,a%b,y,x),y-=a/b*x;}inline bool solve(int m){    for (int i=1;i<n;++i)      for (int j=i+1;j<=n;++j){        a=P[i]-P[j]; b=m; c=C[j]-C[i];        int t=gcd(a,b);        if (c%t) continue;        a/=t; b/=t; c/=t;        exgcd(a,b,x,y);        b=abs(b);        x=((c*x)%b+b)%b;        if (!x) x+=b;        if (x>L[i]||x>L[j]) continue;        else return false;      }    return true;}int main(){    scanf("%d",&n);     for (int i=1;i<=n;++i){        scanf("%d%d%d",&C[i],&P[i],&L[i]);        if (C[i]>Max) Max=C[i];    }    for (int i=Max;;++i)      if (solve(i)){        printf("%d\n",i);        return 0;      }}

总结

break只是跳掉一层循环吗?我以前一直煞笔?
还有就是b/t之后可能变成负数,然后就鬼畜了。。。

0 0
原创粉丝点击