NOIP模拟 弹球 【最大公因数】
来源:互联网 发布:trunk端口配置代码 编辑:程序博客网 时间:2024/05/21 06:35
题目大意
给定一张n*m的格子图,把一个球从(1,1)向右下方射出,到达边上时反弹,直到到再次达到一个角落,问该过程中只走过一次的格子有多少个。(包括起点)(2
如一个9*15的格子图:
答案为39;
解题思路:
直接在格子中处理太困难,不如把它放在一个(n-1)*(m-1)的顶点图中,如上图就变成了:
小球轨迹为图中蓝线。
这样就容易发现,以其轨迹可以分割成了多个边长为a=2*gcd(n-1,m-1)的正方形(图中绿线)。
可以得到小球路程中共经过(n-1)
#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<cmath>#include<vector>#include<queue>#define ll long longusing namespace std;int getint(){ int i=0,f=1;char c; for(c=getchar();(c<'0'||c>'9')&&c!='-';c=getchar()); if(c=='-')f=-1,c=getchar(); for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0'; return i*f;}int T,n,m;int gcd(int a,int b){ return !b?a:gcd(b,a%b);}ll solve(){ n--,m--; ll ans=1ll*n*m/gcd(n,m)+1;//路程中总共经过的点的数目(有重复) int a=gcd(n,m)*2; ll num1=1ll*(n/a)*(m/a);//橙点数目 ll num2=1ll*(n%a==0?n/a-1:n/a)*(m%a==0?m/a-1:m/a);//蓝点数目 ans-=1ll*(num1+num2)*2; return ans;}int main(){ //freopen("lx.in","r",stdin); //freopen("lx.out","w",stdout); T=getint(); while(T--) { n=getint(),m=getint(); cout<<solve()<<'\n'; } return 0;}
阅读全文
0 0
- NOIP模拟 弹球 【最大公因数】
- [NOIP模拟][规律探究]弹球
- NOIP模拟(10.19)T2 弹球
- 最大公因数
- 最大公因数
- 最大公因数
- 最大公因数最小公倍数
- 最小公倍数&最大公因数
- 最大公因数&&最小公倍数
- 最大公因数、最小公倍数、因式分解
- 最大公因数与最小公倍数
- 15 最大公因数、最小公倍数
- 计算最大公因数
- 二分搜索&最大公因数
- 最大公因数与最小公倍数
- 最大公因数与最小公倍数
- NYOJ最大公因数最小公倍数
- 最大公因数与最小公倍数
- 2017-10-19-MySQL SQL_MODE详解
- Garlands UVA
- Android内存泄漏的避免、定位、解决
- 文件系统扫描校对及异常修复处理
- Linux 相关小知识tips
- NOIP模拟 弹球 【最大公因数】
- ThinkPHP学习笔记—自动创建模块
- 算法训练 表达式计算(栈)
- 数据库基本操作
- 卷积神经网络的参数维度(15)---《深度学习》
- D
- 单词翻转
- HTTPS(Hypertext Transfer Protocol Secure)安全超文本传输协议
- esayUI 鼠标悬停提示