程序基本算法习题解析 数轴上有N条线段和M个点,已知每条线段的起点和终点,求每个点共在几条已知的线段上出现过,输出该点出现的次数。

题目:

在一个数轴上有N条线段,已知每条线段的起点和终点的值均在50000以内。有M个点,求每一个点共在几条已知的线段上出现过,并输出该点出现的次数。输入:第一行输入数字N,表示线段条数(N<=50000),接下来的N行,每行输入两个数,作为线段的起点和终点。第N+2行输入数字M,表示要求的点的个数。接下来的M行,每行输入一个整数,表示点的位置(M<=50000)。输出:对于每个输入的点,输出表示其出现次数的数值。

思路:

刚看到这个题目时,我觉得很简单,大致想了一下思路准备略过,后来扫了一眼书上答案,发现书上的思路和我很不一样,因此把此题分享出来,感觉多少能拓展一下解题思维。

我的思路:

将每条线段的起点和终点,每个点的位置,每个位置对应的出现次数分别用一个数组存放,然后遍历每个点(外层循环),遍历每条线段(内层循环),判断该点是否在某条线段上(点的位置大于线段的起点小于线段的终点),如果在某条线段上,则相应点位置上的出现次数加1。

书上思路:

设置一个数组记录每条线段的下标对应点的位置,若有一条线段经过某点,只需在读取这条线段时将该点对应下标的值加1即可,结束此操作后,数组中每个点对应的值即为该点对应的线段数,最后对每个输入的点直接输出该点所在的线段的个数。

代码如下:

(我的思路)

#include "stdafx.h"
#include<iostream>
using namespace std;

//个人思路
int main()
{
	int N,M; //N:线段条数,M:点的个数
	cout << "输入线段条数:";
	cin >> N;
	int *line_begin = new int[N]; //line_begin:线段的起点
	int *line_end = new int[N]; //line_end:线段的终点
	int i,j;
	//输入线段的起点和终点
	for(i=0;i<N;i++)
	{
		cout << "输入第" << i+1 << "条线段的起点和终点:";
		cin >> line_begin[i] >> line_end[i];
	}
	cout << "输入点的个数:";
	cin >> M;
	int *point = new int[M]; //point:点的位置
	int *point_num = new int[M]; //点的个数,对应于point
	//初始化点的个数
	for(i=0;i<M;i++)
	{
		point_num[i] = 0;
	}
	//输入点的位置
	for(i=0;i<M;i++)
	{
		cout << "输入第" << i+1 << "个点的位置:";
		cin >> point[i];
	}
	//遍历每个点
	for(i=0;i<M;i++)
	{
		//遍历每条线段
		for(j=0;j<N;j++)
		{
			//如果点在线段上(点的位置在线段的起点和终点之间)
			if(point[i] >= line_begin[j] && point[i] <= line_end[j])
				point_num[i]++;
		}
	}
	for(i=0;i<M;i++)
	{
		cout << "点" << point[i] << "出现的次数为:" << point_num[i] << endl;
	}
	system("pause");
	return 0;
}

(书上思路)

#include "stdafx.h"
#include<iostream>
using namespace std;
//书上思路
int s,e,p; //s:线段起点,e:线段终点,p:点的位置
int n,m; //n:线段条数,m:点的个数
int v[50010]; //每个单元位置上的点在所有线段中出现次数
int main()
{
	cin >> n; //输入线段条数
	for(int i=0;i<n;i++)
	{
		cin >> s >> e; //输入线段的起点和终点
		for(int j=s;j<=e;j++)
		{
			v[j]++; //将该条线段覆盖到的点都加1
		}
	}
	cin >> m; //输入点的个数
	for(int k=0;k<m;k++)
	{
		cin >> p; //输入点的位置
		cout << "点" << p << "出现的次数为:" << v[p] << endl; //将该位置的点出现次数输出
	}
	system("pause");
	return 0;
}

运行结果如下:

(我的思路)

(书上思路)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值