题意:

给出一个n行m列的点阵,求共有多少条非水平非竖直线至少经过其中两点。

分析:

首先说紫书上的思路,编程较简单且容易理解。由于对称性,所以只统计“\”这种线型的,最后乘2即是答案。

枚举斜线包围盒的大小,如果盒子的长宽ab互质,则是可以的。这种盒子共有(m-a)(n-b)个,但要减去其中重复的。如果有一个长宽为2a和2b的大盒子,则计数右下角的小盒子的同时,左上角的小盒子会重复,所以要减去重复的盒子的个数c = max(0, m-2a) * max(0, n-2b)

最后gcd(a, b)的值是要预处理的

 #include <cstdio>
#include <algorithm> const int maxn = ;
int gcd[maxn+][maxn+]; int GCD(int a, int b)
{
return b == ? a : GCD(b, a%b);
} int main()
{
for(int i = ; i <= maxn; ++i)
for(int j = ; j <= i; ++j)
gcd[i][j] = gcd[j][i] = GCD(i, j); int n, m;
while(scanf("%d%d", &n, &m) == && n)
{
int ans = ;
for(int a = ; a <= n; ++a)
for(int b = ; b <= m; ++b)
if(gcd[a][b] == )
{
int c = std::max(, n-a*) * std::max(, m-b*);
ans += (n-a)*(m-b) - c;
} printf("%d\n", ans * );
} return ;
}

代码君

解法二:

解法转自UVA 1393 - Highways (容斥原理计数)

dp(i, j)表示在长宽为ij的盒子中,从左上角最多能连多少条不重复的直线。

可以根据容斥原理递推dp(i, j) = dp(i-1, j) + dp(i, j-1) - dp(i-1, j-1) + (gcd(i, j) = 1) (因为盒子两边长互质的时候,才能连出一条新边出来)

最后答案ans递推的形式也是一样的,但重复的连线是那些缩小两倍后仍存在的直线

ans(i, j) = ans(i-1, j) + ans(i, j-1) - ans(i-1, j-1) + dp(i, j) - dp(i/2, j/2)

最后代码中,本想着只计算一半答案会快一点,结果排名21,登榜失败。

 #include <cstdio>
#include <algorithm> const int maxn = ;
int dp[maxn+][maxn+], ans[maxn+][maxn+]; int gcd(int a, int b)
{
return b == ? a : gcd(b, a%b);
} void Init()
{
for(int i = ; i <= maxn; ++i)
for(int j = ; j <= i; ++j)
{
if(i == j) dp[i][j] = dp[i][j-] * - dp[i-][j-] + (gcd(i, j) == );
else dp[i][j] = dp[i-][j] + dp[i][j-] - dp[i-][j-] + (gcd(i, j) == );
} for(int i = ; i <= maxn; ++i)
for(int j = ; j <= i; ++j)
{
if(i == j) ans[i][j] = ans[i][j-] * - ans[i-][j-] + dp[i][j] - dp[i/][j/];
else ans[i][j] = ans[i][j-] + ans[i-][j] - ans[i-][j-] + dp[i][j] - dp[i/][j/];
}
} int main()
{
Init();
int n, m;
while(scanf("%d%d", &n, &m) == && n)
{
if(n < m) std::swap(n, m);
printf("%d\n", ans[n-][m-]*);
} return ;
}

代码君

UVa 1393 (容斥原理、GCD) Highways的更多相关文章

  1. uva 1393 - Highways(容斥原理)

    题目连接:uva 1393 - Highways 题目大意:给定一个m∗n的矩阵,将矩阵上的点两两相连,问有多少条直线至少经过两点. 解题思路:头一次做这样的题目,卡了一晚上. dp[i][j]即为i ...

  2. uva 10951 - Polynomial GCD(欧几里得)

    题目链接:uva 10951 - Polynomial GCD 题目大意:给出n和两个多项式,求两个多项式在全部操作均模n的情况下最大公约数是多少. 解题思路:欧几里得算法,就是为多项式这个数据类型重 ...

  3. UVA 10951 - Polynomial GCD(数论)

    UVA 10951 - Polynomial GCD 题目链接 题意:给定两个多项式,求多项式的gcd,要求首项次数为1,多项式中的运算都%n,而且n为素数. 思路:和gcd基本一样,仅仅只是传入的是 ...

  4. UVa 1393 - Highways(数论)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  5. UVA 1393 Highways(数学思想)

    题意:给你n.m(n,m<=200),问你有多少条非水平.非垂直的直线有多少条经过至少两个点 题解:我们需要枚举的是只画一条线的矩形,对于大小a*b的矩形必须保证gcd(a,b)=1才能不重复 ...

  6. UVA 1393 Highways

    https://vjudge.net/problem/UVA-1393 题意: a*b的点阵中能画多少条非水平非竖直的直线 方向‘/’ 和 方向 ‘\’ 对称 枚举直线所在矩形的i*j 直线可能重复的 ...

  7. UVA 1393 Highways,UVA 12075 Counting Triangles —— (组合数,dp)

    先看第一题,有n*m个点,求在这些点中,有多少条直线,经过了至少两点,且不是水平的也不是竖直的. 分析:由于对称性,我们只要求一个方向的线即可.该题分成两个过程,第一个过程是求出n*m的矩形中,dp[ ...

  8. hdu (欧拉函数+容斥原理) GCD

    题目链接http://acm.hdu.edu.cn/showproblem.php?pid=1695 看了别人的方法才会做 参考博客http://blog.csdn.net/shiren_Bod/ar ...

  9. UVa 1642 - Magical GCD(数论)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

随机推荐

  1. linux内核编译,内核参数修改

    核心(kernel):/boot/vmlinuz-version version 带发行包版本,本地版本内核模块(kernel object): /lib/modules/version/ 内核设计: ...

  2. Nginx Location配置总结及基础最佳实践

    参考来源: http://blog.zol.com.cn/1067/article_1066186.html,http://flandycheng.blog.51cto.com/855176/2801 ...

  3. c# 判断点是否在区域内 点在区域内 在多边形内 判断

    方法一 算法 : public int isLeft(Point P0, Point P1,Point P2)        {            int abc= ((P1.X - P0.X) ...

  4. delphi 自带报告内存泄漏

    //报告内存泄漏 ReportMemoryLeaksOnShutdown := true;

  5. 1010. Radix (25)

    Given a pair of positive integers, for example, 6 and 110, can this equation 6 = 110 be true? The an ...

  6. Matlab删除NaN数据

    删除包含NaN的行: a(any(isnan(a), 2),:) = []; 删除全部为NaN的行: a(all(isnan(a), 2),:) = [];

  7. 【POJ2104】kth num

    You are working for Macrohard company in data structures department. After failing your previous tas ...

  8. Vue引发的getter和setter

    Vue引发的getter和setter 公司的新项目决定使用Vue.js来做,当我打印出Vue实例下的data对象里的属性时,发现了一个有趣的事情: 它的每个属性都有两个相对应的get和set方法,我 ...

  9. DataTableExtensions.AsEnumerable 方法

    在下面的示例中,DisplayProducts 方法接收一个数据表,其中包含名为 ProductName一个 DataColumn,提取 ProductName 值,然后输出值. using Syst ...

  10. suse pshell连接不上

    /etc/ssh/sshd_config #PasswordAuthentication no改成yessuse默认为密钥认证