【文文殿下】【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;
}

posted @ 2019-01-05 03:04  文文殿下  阅读(305)  评论(0编辑  收藏  举报