Codeforces 724C Ray Tracing 擴充套件歐幾里得
阿新 • • 發佈:2019-01-03
標籤: 解題報告 數學
n*m的矩形內有k個點,四周有圍牆圍起來。從(0,0)45度發射小球,速度為
分析
把矩形對稱展開,最後小球在橫縱座標均為
原座標為
即要解方程
求ax+by=c最小正整數解,坑點:ran<0時不搞成正數會出錯!
LL equation(LL a, LL b, LL c, LL &x, LL &y)
{
LL g = extend_Euclid(a, b, x, y);
if(c % g) return -1;
LL ran = b / g;
x *= c/g;
if(ran < 0) ran = -ran; //wa point
x = (x%ran + ran) % ran;
return 0;
}
程式碼
/*--------------------------------------------
* File Name: CF 724C
* Author: Danliwoo
* Mail: [email protected]
* Created Time: 2016-10-08 23:37:05
--------------------------------------------*/
#include <bits/stdc++.h>
using namespace std;
#define LL long long
LL n, m;
LL extend_Euclid(LL a, LL b, LL &x, LL &y){
if(b==0){
x = 1; y = 0;
return a;
}
LL r = extend_Euclid(b, a%b, y, x);
y -= a/b*x;
return r;
}
LL equation(LL a, LL b, LL c, LL &x, LL &y)
{
LL g = extend_Euclid(a, b, x, y);
if(c % g) return -1;
LL ran = b / g;
x *= c/g;
if(ran < 0) ran = -ran;
x = (x%ran + ran) % ran;
return 0;
}
LL gao(LL dx, LL dy, LL M) {
LL k, s;
if(equation(2*n, -2*m, -dx+dy, k, s) == -1)
return M + 1;
LL tx = 2 * k * n + dx;
if(tx < 0 || tx > M) return M + 1;
return tx;
}
LL minL(LL a, LL b) {
return a < b ? a : b;
}
LL solve(LL x, LL y) {
LL g = __gcd(n, m);
LL maxx = 1LL * m / g * n;
LL ans = maxx + 1;
ans = minL(ans, gao(-x, -y, maxx));
ans = minL(ans, gao(-x, y, maxx));
ans = minL(ans, gao(x, -y, maxx));
ans = minL(ans, gao(x, y, maxx));
if(ans == maxx + 1) return -1;
return ans;
}
int main() {
int k;
while(~scanf("%I64d%I64d%d", &n, &m, &k)) {
for(int i = 0;i < k;i++) {
LL x, y;
scanf("%I64d%I64d", &x, &y);
printf("%I64d\n", solve(x, y));
}
}
return 0;
}