题意:

给出一个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. 手机淘宝用JS来动态写meta标签(1像素边框处理方法)

    var metaEl = doc.createElement('meta'); var scale = isRetina ? 0.5:1; metaEl.setAttribute('name', 'v ...

  2. Spark Streaming揭秘 Day25 StreamingContext和JobScheduler启动源码详解

    Spark Streaming揭秘 Day25 StreamingContext和JobScheduler启动源码详解 今天主要理一下StreamingContext的启动过程,其中最为重要的就是Jo ...

  3. 【BZOJ 1040】 [ZJOI2008]骑士

    Description Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争.战火 ...

  4. Xcode6中autolayout和sizeclass的使用

    一.关于自动布局(Autolayout) 在Xcode中,自动布局看似是一个很复杂的系统,在真正使用它之前,我也是这么认为的,不过事实并非如此. 我们知道,一款iOS应用,其主要UI组件是由一个个相对 ...

  5. 在scrollView中使用pageControl

    在scrollView中使用pageControl 要这样才能效果好,合理而且人性化 -(void)scrollViewDidScroll:(UIScrollView *)scrollView{ if ...

  6. 在PyCharm里配置SubVersion

    1.如果PyCharm不支持svn ,那么下载svn命令行安装包,下载地址:http://sourceforge.net/projects/win32svn/ 例如:安装到 D:\software\s ...

  7. Excel 隐藏功能区命令

    Application.ExecuteExcel4Macro "SHOW.TOOLBAR(""Ribbon"",False)"

  8. [Jquery] js验证手机号

    function checkIdPhone(id,idErr){ var reg0=/^(13[0-9]|15[012356789]|18[01235,idErr6789]|14[57]|17[0]) ...

  9. uc/os初始化

        操作系统初始化函数OS_INIT是操作系统在开始运行的最初,对全局变量.任务控制块.就绪表.事件及消息队列等重要数据结构进行的初始化操作,并创建空闲任务.统计任务等系统任务.该函数必须在创建用 ...

  10. Akka的fault tolerant

    要想容错,该怎么办? 父actor首先要获知子actor的失败状态,然后确定该怎么办, “怎么办”这回事叫做“supervisorStrategy".   // Restart the st ...