正题
大意
有n个野人,每个野人有一个初始山洞CiCi,每次向前移动距离PiPi,寿命LiLi,如果野人走到了最后一个山洞那么继续就好回到第一个山洞,求至少多少个山洞才可以让野人们不会发生冲突。
解题思路
我们可以枚举答案,然后我们要判断是否冲突,我们可以枚举两个野人然后列出式子:
Ci+Pix≡Cj+Pjx(mod l)Ci+Pix≡Cj+Pjx(modl)
如果这个式子有解且最小解
x<=Li/Ljx<=Li/Lj那么就会有冲突。
我们先把式子转换一下
(Ci−Cj)+(Pi−Pj)x≡0(mod l)(Ci−Cj)+(Pi−Pj)x≡0(modl)
(Ci−Cj)+(Pi−Pj)x=ly(Ci−Cj)+(Pi−Pj)x=ly
(Pi−Pj)x−ly=(Ci−Cj)(Pi−Pj)x−ly=(Ci−Cj)
然后我们进行扩欧
代码
#include<cstdio>
#include<algorithm>
using namespace std;
int x,y,n,c[16],p[16],l[16],maxc,d,A,B,g;
bool flag;
int gcd(int a,int b)//同余
{if (b==0){x=1;y=0;return a;}d=gcd(b,a%b);int k=x;x=y;y=k-a/b*y;return d;
}
int main()
{scanf("%d",&n);for (int i=1;i<=n;i++){scanf("%d%d%d",&c[i],&p[i],&l[i]);maxc=max(maxc,c[i]);}while (1){flag=false;for (int i=1;i<n;i++){for (int j=i+1;j<=n;j++){A=c[i]-c[j];B=p[j]-p[i];if (B<0){A=-A;B=-B;//取反,因为是 -ly}d=gcd(B,maxc);g=maxc/d;g=((x*(A/d))%g+g)%g;//最小解if (!(A%d)&&g<=l[i]&&g<=l[j])//判断{flag=true;break;}}if (flag) break;}if (!flag) break;maxc++;//枚举}printf("%d",maxc);
}