-
题目描述:
-
有一个长度为整数L(1<=L<=10000)的马路,可以想象成数轴上长度为L的一个线段,起点是坐标原点,在每个整数坐标点有一棵树,即在0,1,2,...,L共L+1个位置上有L+1棵树。
现在要移走一些树,移走的树的区间用一对数字表示,如 100 200表示移走从100到200之间(包括端点)所有的树。
可能有M(1<=M<=100)个区间,区间之间可能有重叠。现在要求移走所有区间的树之后剩下的树的个数。
-
输入:
-
两个整数L(1<=L<=10000)和M(1<=M<=100)。
接下来有M组整数,每组有一对数字。
-
输出:
-
可能有多组输入数据,对于每组输入数据,输出一个数,表示移走所有区间的树之后剩下的树的个数。
-
样例输入:
-
500 3 100 200 150 300 470 471
-
样例输出:
-
298
这道题范围比较小,直接用链表维护一个分散的线段序列即可,AC代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int l[110], r[110];
typedef struct Node{
int l, r;
Node* next;
}Node;
int main()
{
int L, m;
while(~scanf("%d%d", &L, &m))
{
memset(l, 0, sizeof(l));
memset(r, 0, sizeof(r));
for(int i = 1; i <= m; i++)
scanf("%d%d", &l[i], &r[i]);
Node *head = new Node();
head->next = NULL;
Node *p = new Node();
p->l = l[1], p->r = r[1];
p->next = NULL, head->next = p;
for(int i = 2; i <= m; i++)
{
Node *pre = head;
Node *tmp = head->next;
while(tmp)
{
if(r[i] < tmp->l)
{
Node *np = new Node();
np->l = l[i], np->r = r[i];
np->next = tmp;
pre->next = np;
break;
}
else if(l[i] < tmp->l && r[i] >= tmp->l)
{
tmp->l = l[i];
tmp->r = max(r[i], tmp->r);
Node *pp = tmp->next;
while(pp)
{
if(tmp->r >= pp->l)
{
tmp->r = max(tmp->r, pp->r);
tmp->next = pp->next;
}
else
break;
pp = pp->next;
}
break;
}
else if(l[i] >= tmp->l && l[i] <= tmp->r)
{
tmp->r = max(r[i], tmp->r);
Node *pp = tmp->next;
while(pp)
{
if(tmp->r >= pp->l)
{
tmp->r = max(tmp->r, pp->r);
tmp->next = pp->next;
}
else
break;
pp = pp->next;
}
break;
}
pre = pre->next;
tmp = tmp->next;
}
if(tmp == NULL) //加在最后一个
{
Node *np = new Node();
np->l = l[i], np->r = r[i];
pre->next = np;
np->next = NULL;
}
}
int len = 0;
Node *pp = head->next;
while(pp)
{
//printf("l:%d r:%d\n", pp->l, pp->r);
len = len+(pp->r-pp->l+1);
pp = pp->next;
}
int ans = L+1-len;
printf("%d\n", ans);
}
return 0;
}