YbtOJ 「同余问题」H.荒岛野人
很容易想到,只要从小到大枚举答案并check就可以了
但这么水的题,为什么我挂了这么多次呢
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/a976a3b0b0648289e516d9309b68811b.png)
-
exGCD求出特殊解后,用不定方程的通解公式取最小正数值时注意up要是正数
-
枚举答案是有下界的,显然不能小于
max
(
c
i
)
\max(c_i)
max(ci)
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=100;
int n;
int c[maxn],p[maxn],l[maxn];
inline int gcd(int a,int b){return b?gcd(b,a%b):a;}
inline void exgcd(int a,int b,int &x,int &y)
{
if(!b){x=1,y=0;return;}
exgcd(b,a%b,x,y);
int t=x;x=y;y=t-(a/b)*y;
}
inline bool check(int M)
{
for(int i=1;i<n;i++)
for(int j=i+1;j<=n;j++)
{
int T=c[i]-c[j];
int S=p[j]-p[i];
if(T<0) S=-S,T=-T;
int GCD=gcd(S,M);
if(T%GCD) continue;
int x,y;
exgcd(S,M,x,y);
x*=(T/GCD);
int up=abs(M/GCD);
x=(x%up+up)%up;
if(x<=l[i]&&x<=l[j]) return false;
}
return true;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);cout.tie(NULL);
cin>>n;
int mx=0;
for(int i=1;i<=n;i++) cin>>c[i]>>p[i]>>l[i],mx=max(c[i],mx);
for(int ans=mx;ans<=1000000;ans++)
if(check(ans)) return cout<<ans<<endl,0;
return 0;
}