CodeForces
来源:互联网 发布:手机模拟笛子软件 编辑:程序博客网 时间:2024/06/18 08:23
点击打开链接
题意:
n*m的矩形内有k个点,四周有围墙围起来。从(0,0)45度发射小球,速度为
思路:
我们试着将这个反射的过程看成穿过,那么需要将整个矩阵展开(即变成一条直线).即所有穿过的都是关于 x==2*k*n,或者y == 2*kk*m进行对称的,根据轴对称性计算坐标进而可以得到每个点的坐标为(2*k*n±x,2*kk*m±y)。我们又发现最后肯定是在 n*m/gcd(n*m)处被吸收. 因为小球是按照y=x的直线运动,所以当 2*k*n±x=2*kk*m±y 有解.因为求第一次被经过的时刻,所以这里的2*k*n和2*kk*m应当为最小, 即 2*k*n-2*kk*m = ±(x±y) ,这里x,y已知,我们要求的就是最小的k,kk使得等式成立.
上述这个问题可以用扩展欧几里得来解决,即 a*x+b*y = c,求一组可行解使得等式成立(最小解)
#include <bits/stdc++.h> using namespace std;typedef long long ll;ll n,m,k;ll ex_gcd(ll a, ll b, ll &x, ll &y){ if(b==0){ x = 1; y = 0; return a; } ll tmp = ex_gcd(b, a%b, y, x); y -= a/b*x; return tmp; } ll cal(ll a, ll b, ll c,ll & x,ll &y) { ll g = ex_gcd(a, b, x, y); if(c % g) return -1; x *= c/g; b /= g; if(b < 0) b = -b; //ran < 0 时候要变成正数 x = (x % b + b) % b; return 0;} ll gao(ll dx, ll dy, ll M) { ll k, s; if(cal(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%I64d", &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; }
阅读全文
0 0
- codeforces~~~
- Codeforces
- codeforces
- Codeforces
- codeforces
- codeforces
- Codeforces
- Codeforces
- CodeForces
- CodeForces
- CodeForces
- CodeForces
- CodeForces
- Codeforces
- Codeforces
- Codeforces
- Codeforces
- Codeforces
- rpm与yum 基础 常见命令
- 文档总结6-linux文档权限
- leetcode--19. Remove Nth Node From End of List
- [HDU] 3966 树状数组+启发式树链剖分
- java.lang.Exception: No runnable methods
- CodeForces
- C++继承和派生
- Linux内核参数解析
- Rust : 递归、效率与替代、溢出
- ubuntu 开启SSH服务
- 随机生成汉字图片
- 动态规划
- 进程间通讯--管道
- PHP学习笔记——使用回调函数处理数组函数array_map()