算法作业 (二)——— 校门口的树
上周因为社团纳新拉下了上一次的题,这周补上的算法作业。
上周的算法题相当简单,大家基本应该是耳熟能详——校门口的数,题目如下:
图找不到了,去洛谷上偷了一下题目,嘿嘿。
读完这道题,马上发现这道题有两个坑。第一个坑是,去重 ,不能砍过又砍,斩草除根有点说不过去了,第二个坑点是,两端都有树,记得加1。但是这个与第一个相比简直是太简单了。第一个坑一般人都会去将两个数相减,然后判断是否有重复区域,有就加上重复区域的树,如果你如此写了,那基本上就踩上了这个大坑,看看数据组最大100组,光去重你就可以写上好久了。所以我们另辟蹊径,先看数据数据范围L <= 10000, 嗯,数据很小,所以我产生了开桶的思路,桶里为0,有树;桶里为1,树被砍。那么只要检测一下是不是桶里是不是有树就可以去除重。
下面我们来实现一下核心代码:
for ( j = start; j <= end; j++ ) { if ( 0 == a[j] ) //砍过的树会被过滤 { a[j] = 1; count++; } }
对于这道题我可以边读边处理数据无需长久存储,可以节省一点空间得到以下代码:
#include <stdio.h> #include <stdlib.h> /** * @author 杨文蓁的小迷弟 * @note 算法作业2 * @date 2019/09/03 */ int main() { int i, j, L, times, start, end, count; int a[10001] = {0}; count = 0; while ( ~scanf( "%d%d",&L ,× ) ) { for ( i = 0; i < times ;i++ ) { scanf( "%d%d",&start ,&end ); for ( j = start; j <= end; j++ ) { if ( 0 == a[j] )C { a[j] = 1; count++; } } } printf( "%d\n", 1+L-count ); } return 0; }
好了,赶工完成。
再贴一个Python的代码
s = input().split() L = int(s[0]) M = int(s[1]) arr = [] counter = 0 for i in range(L+1): arr.append(True) for i in range(M): s = input().split() for j in range(int(s[0]), int(s[1]) + 1): if arr[j] == True: arr[j] = False counter += 1 print(L-counter+1)
大道五十,天衍四九,人遁其一!