思路
考虑结合数学数轴上面的线段知识来解决。有交集时,若在线段范围中,进行范围合并,若超出范围,则进行范围延长;若无交集则单独成段。例如:
-
输入 #1
500 3 150 300 100 200 470 471
-
作图如下
-
测试样例
代码
- C++ 实现
// -*- coding: utf-8 -*-
// @ Date : 2020/5/20 13:14
// @ Author : RichardLau_Cx
// @ file : Richard.cpp
// @ IDE : Dex-C++
// @ Source : luogu
#include <iostream>
using namespace std;
int main()
{
int l; // 马路长度
int m; // 区域的数目
int index = 0; // 初始放至于0号索引
int add = 0; // 端点需要移除的树
cin >> l >> m;
int points[m+1][2]; // 存放m个区域的起始点坐标,空出一行用来做交换
int remainder = l; // 剩余的树木数量
// while(m--)
// { // 此方法不适合结合重合部分
// int u, v; // 一个区域的起始点和终止点的坐标
// cin >> u >> v
// }
for (int i=0; i < m; i++)
{
cin >> points[i][0] >> points[i][1];
/*
if (points[i][0] > points[i][1])
{ // 考虑到给定的起始位置可能为倒序,如:起始点位置 < 终止点位置时,把顺序调整为升序, => 题目中已经表明:0 <= u <= v <= l
int temp = points[i][0];
points[i][0] = points[i][1];
points[i][1] = temp;
}
*/
}
for (int i=0; i < m-1; i++)
{ // 处理思路:排序 + 判断
for (int j=0; j < m-1; j++)
{
// cout << "here!" << endl;
if (points[j][0] > points[j+1][0])
{
// points[m][0], points[m][1] = points[j][0], points[j][1];
points[m][0] = points[j][0];
points[m][1] = points[j][1];
// points[j][0], points[j][1] = points[j+1][0], points[j+1][1];
points[j][0] = points[j+1][0];
points[j][1] = points[j+1][1];
// points[j+1][0], points[j+1][1] = points[m][0], points[m][1];
points[j+1][0] = points[m][0];
points[j+1][1] = points[m][1];
}
}
}
/*
cout << endl << endl << "begin: " << endl;
for (int i=0; i < m; i++)
{
cout << points[i][0] << ' ' << points[i][1] << endl;
}
cout << "end: " << endl << endl << endl;;
*/
// for (int i=0; i < m; i++)
// {
// cout << points[i][0] << ' ' << points[i][1] << endl;
// }
for (int i=1; i < m; i++)
{
// cout << "here" << i << endl;
if (points[index][1] >= points[i][0])
{
if (points[index][1] < points[i][1])
{ // 同时左边的终止点小于右边的终止点,扩大范围
points[index][1] = points[i][1];
}
// 证明发生了交集,重复和多余区域置零
points[i][0]=0, points[i][1]=0;
}
else
{ // 未发生交集,索引后跳
index = i;
add++;
}
}
for (int i=0; i < m; i++)
{
remainder -= points[i][1] - points[i][0];
}
// cout << "begin: " << endl;
// for (int i=0; i < m; i++)
// {
// cout << points[i][0] << ' ' << points[i][1] << endl;
// }
// cout << "remainder: " << remainder-add << endl;
cout << remainder-add << endl;
return 0;
}
// TODO : 排序和左右数据调整存在问题,考虑优化排序方式 --- 现已优化