UVa 1393 / LA 3720 Highways

本文探讨了一种使用递推法解决特定道路建设问题的方法,通过分析新建道路上需要建设道路的条件,提出了一种高效的算法实现。文章详细介绍了如何判断两点间是否需要建设道路的完整条件,并分享了代码实现技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一开始以为要用欧拉函数解决,看了半天,发现怎么套都套不上去,只好换个角度思考,由于是递推专题,就用递推的思路尝试一下,如果nm列的所有道路都已经建好。现在新添加一行,即第n+1行,会有哪些道路需要建设?

先看第n+1行的第一个点a,再选择一个非同行同列的点b,若ab之间没有道路,需要满足哪些条件?

ab之间没有道路就必须满足ab之间的道路没有经过其它点,即ab之间的横纵坐标之差互质。想到这就自以为解决问题了。

 

后来发现互质只是条件之一,若有另外一点ca的横坐标之差和纵坐标之差都是b的两倍,那么ab的道路就已经存在。所以完整的条件是ab互质且没有任何一点与a的横坐标之差和纵坐标之差都是b的两倍

 

在代码实现时还需要一些小技巧来加速。详见代码

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 const int maxn = 333;
 7 int c[maxn][maxn];
 8 
 9 int gcd(int a, int b)
10 {
11     return b ? gcd(b, a % b) : a;
12 }
13 
14 void init()
15 {
16     int i, j, k, n = 300;
17     memset(c, 0, sizeof(c));
18     for(i = 1; i <= n; i ++)
19         for(j = 1; j <= n; j ++)
20         {
21             k = gcd(i, j);
22             if(k == 1)
23                 c[i][j] = 1;
24             else if(k == 2)
25                 c[i][j] = -1;
26         }
27 
28     for(i = 1; i <= n; i ++)
29         for(j = 2; j <= n; j ++)
30             c[i][j] += c[i][j - 1];
31 
32     for(i = 2; i <= n; i ++)
33         for(j = 1; j <= n; j ++)
34             c[i][j] += c[i - 1][j];
35 }
36 
37 int main()
38 {
39     int n, m, i, j, ans;
40     init();
41     for(;scanf("%d%d", &n, &m), n + m;)
42     {
43         if(n > m)
44             swap(n, m);
45         ans = 0;
46         for(i = 1; i < n; i ++)
47             for(j = 0; j < m; j ++)
48                 ans += c[i][m - 1 - j] + c[i][j];
49         printf("%d\n", ans);
50     }
51     return 0;
52 }

 

转载于:https://www.cnblogs.com/xchaos/p/3293113.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值