题意:

给出一个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. Dapper.ColumnMapper 的使用

    using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; usin ...

  2. C# 判断点是否在多边形内

    /// <summary>/// 判断点是否在多边形内/// </summary>/// <param name="pnt">点</par ...

  3. 字符设备驱动中cdev与inode、file_operations的关系

    一.cdev与inode 二.cdev与file_operations

  4. python中执行javascript代码

    python中执行javascript代码: 1.安装相应的库,我使用的是PyV8 2.import PyV8 ctxt = PyV8.JSContext()     ctxt.enter()     ...

  5. iOS 基础 第二天(0805)

    0805 面向对象三大特性 封装.继承和多态 oc的方法都是在运行过程中才会检测的.编译时方法没实现只会出现警告,运行时出错.如果方法实现了但没有声明,运行时对象仍然可以调用方法不会出错.这是OC中弱 ...

  6. mac 如何让文件隐藏

    1.首先,要确保知道目标文件或文件夹的名称,你不把这个名称正确地输入到终端中,Mac也无能为力啊... 2.打开终端,输入chflags hidden 3.在上述代码的后面加上该文件夹的路径,但是注意 ...

  7. C#列表顺序替换思想

    /// <summary> /// 显示列顺序 /// </summary> /// <param name="list"></param ...

  8. [搜片神器]BT管理程序数据库速度调试优化问题

    DHT抓取程序开源地址:https://github.com/h31h31/H31DHTDEMO 数据处理程序开源地址:https://github.com/h31h31/H31DHTMgr 谢谢园子 ...

  9. Java发送邮件(带附件)

    实现java发送邮件的过程大体有以下几步: 准备一个properties文件,该文件中存放SMTP服务器地址等参数. 利用properties创建一个Session对象 利用Session创建Mess ...

  10. 【扩展欧几里得】Codevs 1200: [noip2012]同余方程

    Description 求关于 x 同余方程 ax ≡ 1 (mod b)的最小正整数解. Input Description 输入只有一行,包含两个正整数 a, b,用 一个 空格隔开. Outpu ...