线段覆盖

18 篇文章 0 订阅
2 篇文章 0 订阅
题目描述 Description

    给定x轴上的N(0<N<100)条线段,每个线段由它的二个端点a_I和b_I确定,I=1,2,……N.这些坐标都是区间(-999,999)的整数。有些线段之间会相互交叠或覆盖。请你编写一个程序,从给出的线段中去掉尽量少的线段,使得剩下的线段两两之间没有内部公共点。所谓的内部公共点是指一个点同时属于两条线段且至少在其中一条线段的内部(即除去端点的部分)。


输入描述 Input Description

    输入第一行是一个整数N。接下来有N行,每行有二个空格隔开的整数,表示一条线段的二个端点的坐标。


输出描述 Output Description

    输出第一行是一个整数表示最多剩下的线段数。


样例输入 Sample Input
3
6  3
1  3

2  5


样例输出 Sample Output

2


数据范围及提示 Data Size & Hint

0<N<100

先吐槽自己没有看清题OTL, 理解成输几组线段上去,然后去掉连段里面的重合部分,合并相连接的部分,然后输出剩下的线段(搞复杂了)2333

错误代码如下:

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
struct points<span style="white-space:pre">				</span>//线段坐标
{
	int a;
	int b;
};
bool operator<(const points & m, const points & n)  //给sort()用的
{
	return m.a < n.a;

}
int main()
{
	int n, a, b, temp;
	points T;
	cin >> n;
	vector<points> line;
	for (int i = 1; i <= n; i++)
	{
		cin >> a >> b;
		if (a > b)
		{
			temp = a;
			a = b;                    //确保a<b
			b = temp;
		}
		T.a = a;
		T.b = b;
		line.push_back(T);
	}
	vector<points>::iterator pr1, pr2;      
	sort(line.begin(), line.end());     //先按照坐标左端点排序
	int lines = n;
	for (pr1 = line.begin(); pr1 != line.end(); ) 
	{
		for (pr2 = pr1 + 1; pr2 != line.end();)
		{
			if (pr2->a < pr1->b)             //判断线段是否相交
			{
				if (pr2->b > pr1->b)<span style="white-space:pre">		</span>// 判断线段是否被包括了
				{
					temp = pr1->b;
					pr1->b = pr2->a;
					pr2->a = temp;
				}
				else
				{
					temp = pr1->b;
					pr1->b = pr2->a;
					pr2->a = temp;
				}

			}
			else if (pr1->b == pr2->a)        //相连接就合并
			{
				pr1->b = pr2->b;
				pr2->a = pr2->b;
			}

			if ((pr2->b - pr2->a) == 0)     //判断线段是否减少
			{
				lines--;
				pr2 = line.erase(pr2);
			}
			else
				pr2++;

		}
		if (pr1->b - pr1->a == 0)    //<span style="font-family: Arial, Helvetica, sans-serif;">判断线段是否减少</span>
		{
			lines--;
			pr1 = line.erase(pr1);
		}
		else
			pr1++;
	}
	cout << lines;
	return 0;
}



下面是AC的代码:

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
struct points
{
	int a;
	int b;
};
bool operator<(const points & m, const points & n)
{
	return m.a < n.a;

}
int main()
{
	int n, a, b, temp;
	points T;
	cin >> n;
	vector<points> line;
	int * exist = new int[n+1];
	for (int i = 1; i <= n; i++)
	{
		cin >> a >> b;
		if (a > b)
		{
			temp = a;
			a = b;
			b = temp;
		}
		T.a = a;
		T.b = b;
		line.push_back(T);
		exist[i] = 1;
	}
	vector<points>::iterator pr1, pr2;
	sort(line.begin(), line.end());
	int i, j;
	for (pr1 = line.begin() ,i = 1; pr1 != line.end(); i++,pr1++)
	{
		for (pr2 = line.begin(), j = 1; pr2 != pr1; pr2++ , j++)
		{
			if (pr2->b <= pr1->a)
			{
                <span style="white-space:pre">		</span>exist[i] = max(exist[i], exist[j]+1);    //记录没有覆盖的线段数
			}
		}

	}
	int ans = 1;
	for (int i = 1; i <= n; i++)
        if (exist[i] > ans)
            ans = exist[i];
	cout << ans;
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值