【文文殿下】【CF724C】Ray Tracing (中国剩余定理)

题解

我们考虑将棋盘扩大一倍,这样相当于取膜。然后,我们只要对x,y,的位置分类讨论,做四次crt就行。具体细节看文文代码。

#include<cstdio>
#include<algorithm>
typedef long long ll;
const ll inf = 1000000000000LL;
int a[10],m[10];
inline ll exgcd(ll a,ll b,ll &x,ll &y) {
    if(b==0) {
        x=1;y=0;
        return a;
    }
    ll d = exgcd(b,a%b,x,y);
    ll tmp = x;
    x=y;
    y=tmp-a/b*y;
    return d;
}
inline ll China() {
    ll A=a[1],M=m[1],k,y;
    for(int i = 2;i<=2;++i) {
        ll d = exgcd(M,m[i],k,y),mod=(m[i]/d),c=a[i]-A;
        if(c%d) return inf;
        k=(k*c/d%mod+mod)%mod;
        A+=k*M;M*=m[i]/d;A=(A+M)%M;
    }
    return A;
}
inline ll solve(ll x,ll y) {
    a[1]=x;
    a[2]=y;
    return China();
}
int aa,bb,k;
int main() {
    //freopen("test.in","r",stdin);
    scanf("%d%d%d",&aa,&bb,&k);
    while(k--) {
        m[1]=2*aa;
        m[2]=2*bb;
        int x,y;
        scanf("%d%d",&x,&y);
        ll ans = inf;
        ans=std::min(ans,solve(x,y));
        ans=std::min(ans,solve(x,m[2]-y));
        ans=std::min(ans,solve(m[1]-x,y));
        ans=std::min(ans,solve(m[1]-x,m[2]-y));
        if(ans==inf) puts("-1");
        else printf("%lld\n",ans);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Syameimaru/p/10223238.html