[algorithm] 对角线经过的矩形数目

博问里面的一个问题,有一点意思,小记录一下。

Problem


将N * M个边长为一的正方形拼成一个N* M的矩形( 每行M个小正方形,共N行 ),现在从矩形的左上角到右下角连一条线,求这条线“经过”多少个小正方形。其中,"经过"表示该线和小正方形有无穷多个交点,即恰好过一个顶点不算。第一行:T表示T组测试数据, T <= 100,接下来T行,每行N和M, N, M <= 10 ^ 4, 表示N * M个小正方形。对于每个测试数据输出一行,一个整数R,表示经过R个正方形。

Analysis


N*M(N行,M列)的矩形,内部是一个个的网格;

2*2:经过2个   3*2:经过4个 4*2:经过4个

2*3:经过4个   3*3:经过3个 4*3:经过6个

2*4:经过4个   3*4:经过6个 4*4:经过4个

2*5:经过6个   3*5:经过7个 4*5:经过8个

从以上的例子可以发现:

1: 如果M和N没有公约数,那么经过的正方形个数就是M+N-1

  画图看一下比较容易发现这一点,N*M一共含有N-1横边和M-1条竖边,左上角的一个矩形是一定经过的,之后对角线想要进入下一个矩形,必须要经过一条内部的边(横边或者竖边),一共经过经过N-1+M-1条内部边(因为每走一步必定经过一个边),也就是N-1+M-1个矩形加上最左上角的一个矩形,这就是N+M-1个矩形。

2:如果M和N有公约数,那么经过的正方形个数就是M+N-gcd(M,N)

    其实这种情况就是对角线经过正方形交点的情况,有多少个正方形的交点位于这条线上呢?一共是gcd(M,N)-1个点。首先把这条线稍微偏移一点来避开这些交点,根据1的分析,那么经过的矩形是M+N-1个;但是这种偏移会在每一个交点位置上添加一个经过的矩形,可以在纸上画一下,很好理解,因为一共有gcd(M,N)-1个交点,也就是多出了(M和N的最大公约数)-1个矩形。减掉这些多的矩形就可以得到实际经过的矩形数:

M+N-1-(gcd(M,N)-1) = M+N-gcd(M,N);

  1和2两种情况可以合并起来,经过的矩形数目是:M+N-gcd(M,N),问题转换为求M和N的最大公约数,简单很多了。

posted @ 2012-03-22 00:58  zsounder  阅读(1790)  评论(1编辑  收藏  举报