【NOIP模拟】斯洛克

题面

考虑这样一个斯诺克球台,它只有四个袋口,分别在四个角上(如下图所示)。我们把所有桌子边界上的整数点作为击球点(除了 4 个袋口),在每个击球点我们可以 45度角击球。每一个击球点你都可以向两个方向击球,例如像下图所示,从 S 点击球有两种路线。

提供桌子的尺寸,你的任务是计算出有多少种不同的击球方式使得球能入袋。球可视为质点,且无任何阻力,反弹时无能量损失。

输入格式
仅一行,两个整数 m 和 n,2 ≤ M,N ≤ 10^5,表示球台的长和宽。

输出格式
符合以上描述的击球路线数量。

分析

一脸不可做

虽然正解也就是模拟,但是好像很多人还是挂了,有写bfs的,有写了700+行的,我也不知道写了个啥??虽然也有julao写了60行的模拟,用了些goto之类的

但是我菜啊,拿着这个题就开始画图,画了四五十分钟,画了十多个矩形,瞎找了个规律,结果得了90分,还是不错

考完了过后得julao帮助,找到了规律的升级版(我觉得正解应该加一条:找规律!!)

我先开始就胡乱画,后来发现不太对啊,就从终点开始画,然后发现有一组输入3 5 ,输出24的数据,刚好是图上有两根线的边界点的数量*2,于是我再尝试偶数,发现有一点不一样。

90分的规律:

1.n=m 0种
2.n和m都是偶数((n-2)+(m-2))*2-->2*(n+m)-8
3.n和m都是奇数 (n+m)*4-8
4.n和m一奇一偶 (n+m-2)*4 -->(n+m)*4-8

是通过这样的矩形(我可能画了十多个吧ovo)找出来的

即手动模拟bfs,从终点开始算,深红色的线是第一步,粉色线是第二步,黄色线是第三步,天蓝色第四步,海蓝色第五步

一直画线,直到没有可以画的线,可以发现,除了四个顶点,每个点都有两种路线,一定能走到任意一洞里。所以计算出点的数量(n-1+m-1)*2,再*2,就是路线数,就是(n+m)*4-8

然而!这只是n和m互质的情况,如果不互质,比如2和4,6和3,就不满足了(可以画一下),所以这也是为什么我先开始的规律分了奇偶(但是因为画图画着画着就停止运行了,本来还要画一下4*8的矩阵,就没去画,于是没找到深层规律)

如何解决呢?

这两个矩阵是2*3和4*6的,这样画出来可以发现,里面的线是一模一样的!!只是后图因为比例放大了,线就更稀疏了。因为线是一样的,那能到边界的点的数量明显也是一样的,所以对于不互质的情况,我们只需要算出它等比例缩小的最小矩阵的路线数量即可。

时间复杂度从O(N)降低到了O(logN),关键是,模拟不好写,规律就很好写了【虽然画图也画了挺久,但也比花同样时间写模拟或者搜索最后写挂了好吧...】

我承认我思路清奇,1e5的数据都能想着找规律...

#include<bits/stdc++.h>
using namespace std;
int n,m;
int main()
{
    cin>>n>>m;
    cout<<(4*(n+m)/__gcd(n,m))-8;
    return 0;
}
“Make my parents proud,and impress the girl I like.”
原文地址:https://www.cnblogs.com/NSD-email0820/p/9530997.html