P1047 校门外的树

题目描述

某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是11米。我们可以把马路看成一个数轴,马路的一端在数轴00的位置,另一端在LL的位置;数轴上的每个整数点,即0,1,2,…,L0,1,2,,L,都种有一棵树。

由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。

输入格式

第一行有22个整数 L(1 \le L \le 10000)L(1L10000) 和 M(1 \le M \le 100)M(1M100),LL代表马路的长度,MM代表区域的数目,LL和MM之间用一个空格隔开。
接下来的MM行每行包含22个不同的整数,用一个空格隔开,表示一个区域的起始点和终止点的坐标。

输出格式

11个整数,表示马路上剩余的树的数目。

输入输出样例

输入 #1复制
500 3
150 300
100 200
470 471
输出 #1复制
298

说明/提示

NOIP2005普及组第二题

对于20\%20%的数据,区域之间没有重合的部分;

对于其它的数据,区域之间有重合的情况。

解决思路

这条题目有两个解法,简单暴力的一种,是设置一个L长度的数组作为标记,如果树被移走,置为1,最后统计1的数目,这种解法中,对重复的置1效果是相同的,但是空间复杂度高;另外很自然的一种想法是判断是否有重叠,有重叠则合并两个段,我按这个思路完成代码,但是只能通过40%的用例,导出洛谷的输入,发现可能存在这种输入情况: [2,5] [6, 8], [3,7],第一段和第二段不重叠,但是第三段和第一段、第三段和第二段都存在重叠,按自然的输入顺序合并,最后的段是[2, 7] [6, 8],显然存在错误,为解决这种问题,就要先对输入的段按左边界增序排序,然后再处理。

 

代码

#include
#include

using namespace std;

struct seg {
int begin;
int end;
};

#define LENGTH(b, e) (e - b + 1)

int overlap(int a0, int a1, int b0, int b1)
{
return !(a1 < b0 || a0 > b1);
}

int calc(int L, int n, struct seg * array)
{
struct seg * elements = new struct seg [n];
int num = 0;
int i,j,k;

for(i=0; i
/*overlap ?*/
for(j=0; j
if(overlap(elements[j].begin, elements[j].end, array[i].begin, array[i].end)) {
elements[j].begin = min(elements[j].begin, array[i].begin);
elements[j].end = max(elements[j].end, array[i].end);
break;
}
}

/*not overlay*/
if(j >= num) {
elements[num].begin = array[i].begin;
elements[num].end = array[i].end;
num++;
}
}

int sum = 0;

for(i=0; i
if(elements[i].begin == -1) {
continue;
}

sum += (elements[i].end - elements[i].begin + 1);
//printf("begin:%d end:%d\r\n", elements[i].begin, elements[i].end);
}

return L + 1 - sum;
}

bool cmp(struct seg &a, struct seg &b)
{
return a.begin < b.begin;
}

int main(int argc, char **argv)
{
int L = 500;
int num = 3;
struct seg *array;

while(cin >> L)
{
cin >> num;

array = new struct seg [num];

for(int i=0; i
cin >> array[i].begin;
cin >> array[i].end;
}

sort(array, array + num, cmp);

cout << calc(L, num, array) << endl;
}

return 0;
}

你可能感兴趣的:(P1047 校门外的树)