求线段上格点的个数

给定平面上的两个格点p1=(x1,y1), p2=(x2,y2),线段p1p2上,除了p1和p2意外一共有几个格点?

例如:输入:p1=(1,11)   p2=(5,3)

输出3   //这三个点分别是(2,9),(3,7),(4,5)

一个有用的结论:

所求线段间格点的个数n=gcd(abs(y2-y1),abs(x2-x1))-1;

 

这道题目涉及计数问题,主要是通过排列组合的思想计算棋盘中方形和矩形的数量。以下是详细的解答过程。 --- ### 解题思路 1. **正方形的总数** 正方形的特是长和宽相等。对于一个 $n \times m$ 的棋盘: - 边长为 $k$ ($k \leq \min(n, m)$) 的正方形共有 $(n-k+1) \cdot (m-k+1)$ 个。 - 总结起来就是枚举每个可能的边长 $k$,然后累加对应的正方形数目。 2. **长方形(不含正方形)的总数** 矩形的特是可以有不同的长度和宽度。对于任意选择的一条水平线段和一条垂直线段所围成的部分就是一个矩形。 - 所有的矩形(含正方形)数目为 $\frac{n \cdot (n+1)}{2} \cdot \frac{m \cdot (m+1)}{2}$ (这是从每行和每列中选取两条边界的所有可能组合)。 - 再从中减去上面已经统计过的正方形的数目即可得到纯长方形的数量。 --- ### 实现代码(C语言) 下面是基于以上分析的一个实现方案: ```c #include <stdio.h> int main() { int n, m; // 输入n和m scanf("%d%d", &n, &m); long long square_count = 0; long long rectangle_total = ((long long)n * (n + 1)) / 2 * ((long long)m * (m + 1)) / 2; // 计算正方形数量 for (int k = 1; k <= n && k <= m; k++) { square_count += (long long)(n - k + 1) * (m - k + 1); } // 长方形数量等于所有矩形数量减去正方形数量 long long rectangle_only = rectangle_total - square_count; // 输出结果 printf("%lld\n", square_count); // 第一行输出正方形数量 printf("%lld\n", rectangle_only); // 第二行输出仅限于长方形的数量 return 0; } ``` --- ### 示例解释 假如输入 `n=2, m=3`, - 先看正方形部分: - 边长为 1 的正方形:$(2-1+1)\times(3-1+1)=6$ - 边长为 2 的正方形:$(2-2+1)\times(3-2+1)=2$ 因此总计有 $6+2=8$ 个正方形。 - 接着看矩形总部分: $$\text{所有矩形}= \binom{2+1}{2}\times\binom{3+1}{2}=\left(\frac{(2\times3)/2}\right)*(\frac((3*4))/2$$ 最终得出的答案与样例一致。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值