C语言巧用数组之《校门外的树》&个人的一些见解

C语言巧用数组之《校门外的树》+个人的一些见解

作为一个阅读能力比较差的同学,拿到一个问题描述非常长的题目是很苦恼的一件事。
在复习C语言时,看到acm上的一个题目,题目描述对我来说是比较长的了,但是题目却比较简单。
今天在这篇博客里,面对这么多大佬,卖弄一下,发表一些我的经验。
读者可以暂时跳过以下原题部分,直接看我的 个人体会

【原题目】

某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米。我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置;数轴上的每个整数点,即0,1,2,……,L,都种有一棵树。
由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。
输入
数据有多组,对于每组输入:
输入的第一行有两个整数L和 M,L代表马路的长度,M代表区域的数目,L和M之间用一个空格隔开。接下来的M行每行包含两个不同的整数,用一个空格隔开,表示一个区域的起始点和终止点的坐标。
数据范围
1 <= L <= 10000, 1 <= M <= 100
输出
对于每组数据:
输出包括一行,这一行包含一个整数,表示马路上剩余的树的数目。
样例输入

500 3
150 300
100 200
470 471

样例输出

298

【个人体会】

拿到这个题目之后,我首先是比较烦恼的,看了三遍题目描述才明白是怎么回事,再看数据的时候发现这就是一个很简单的题目。
【简化描述】
先给定一条线上树的数量,每隔一米一棵树。有几段树要砍掉,在总树量的那一行给出段数。接下来每一行都将会给出起始位置,即第几米开始到第几米结束。
【解析】
第一眼看到题目,解题思路大致是要去做减法,把要砍掉的树减去即可。
但是实际操作,构建代码体系的时候会发现,这些要砍掉的树段中会出现重复的现象,做减法显然已经变得比较麻烦。
由此便可以想到题目中说到的坐标轴,不妨用数组构建一个坐标轴,即先使用相同的数据将坐标轴填充,再去用另一种数据代表砍掉的树。这样一来题目便简单多了。
【代码&注释】

#include<stdio.h>
int main()
{
	int i,j,k,n,m,M,s=0;
	//在定义变量的时候,个人是比较习惯盲目地去设一些变量
	//比如本题中要使用数组,便直接将i,j等循环使用的变量先设出来
	//这里可以不用先定义数组,因为不确定数组的长度(树总量),所以先扫描导入数组长度再行定义
	scanf("%d %d",&M,&i);
	int a[M];
	//第一行的数据读取完了,可以定义数组和计算次数(要砍的树段数)了
	for(k=0;k<=M;k++)
		a[k]=1;
	//这个循环是使用相同数据填充数组,即将树“种上”
	for(j=0;j<i;j++){
		scanf("%d %d",&m,&n);
		for(k=m;k<=n;k++)
			a[k]=0;
	}
	//用不同数据将要去掉的段改变,即“砍树”
	for(k=0;k<=M;k++)
		if(a[k]==1)
			s++;
	//计算剩余未改变数据数量,剩余的树量
	printf("%d",s);
} 

【代码】

#include<stdio.h>
int main()
{
	int i,j,k,m,n,M,s=0;
	scanf("%d %d",&M,&i);
	int a[M];
	for(k=0;k<=M;k++)
		a[k]=1;
	for(j=0;j<i;j++){
		scanf("%d %d",&m,&n);
		for(k=m;k<=n;k++)
			a[k]=0;
	}
	for(k=0;k<=M;k++)
		if(a[k]==1)
			s++;
	printf("%d",s);
} 

【理解】
在我们使用C语言解决问题的时候,可以将要解决的问题理解成一个工程,指针、数组是我们要用的大材料。
在构建思路的时候,可以将一些问题抽象化,再简单化。比如本题中将数组中的数据抽象成一棵棵树;再用不同数据表示已经砍掉的树,这时便在这个抽象的过程中将问题简化。

  • 16
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 16
    评论
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值