# [NOIP2005 普及组] 校门外的树
## 题目描述
某校大门外长度为 $l$ 的马路上有一排树,每两棵相邻的树之间的间隔都是 $1$ 米。我们可以把马路看成一个数轴,马路的一端在数轴 $0$ 的位置,另一端在 $l$ 的位置;数轴上的每个整数点,即 $0,1,2,\dots,l$,都种有一棵树。
由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。
## 输入格式
第一行有两个整数,分别表示马路的长度 $l$ 和区域的数目 $m$。
接下来 $m$ 行,每行两个整数 $u, v$,表示一个区域的起始点和终止点的坐标。
## 输出格式
输出一行一个整数,表示将这些树都移走后,马路上剩余的树木数量。
## 样例 #1
### 样例输入 #
500 3
150 300
100 200
470 471
### 样例输出 #
298
## 提示
**【数据范围】**
- 对于 $20\%$ 的数据,保证区域之间没有重合的部分。
- 对于 $100\%$ 的数据,保证 $1 \leq l \leq 10^4$,$1 \leq m \leq 100$,$0 \leq u \leq v \leq l$。
对于树之类的题目,本人甚是头疼,哎!具体的内容看如下 来吧 展示!
思路:
第一遍,将路上的所有树打上标记,表示这个点没有被访问过。
第二遍,读入区间的头和尾,从这个区间的头开始循环,到尾结束,标记为访问过。
第三遍,顺序访问路上的树,只要没访问过,计数加1,这样就求出了路上所有还存在的树的数目。
#include<cstdio>
#include<iostream>
using namespace std;
#include<cstring>
//以上不解释,应该都明白
int L,M;
//变量名称与原题相同
int cnt=0;
//剩余树的数目
int vis[10000+10];
//用来判断树木有没有被访问过
int main()
{
memset(vis,0,sizeof(vis));//初始化该数组
cin>>L>>M;//标准输入,不解释
for(int i=0;i<=L;i++)
vis[i]=0;//从0这个树开始,将这条路上所有的树标记为未访问过
for(int i=1;i<=M;i++)
{
int head,tail;//定义区间的头和尾
cin>>head>>tail;
for(int j=head;j<=tail;j++)
if(vis[j]==0)
vis[j]=1;//从这个区间的头和尾开始,将所有区间内的树标记为访问过
}
for(int i=0;i<=L;i++)
{
if(vis[i]==0)
cnt++;//计算未被访问过的树的数目
}
cout<<cnt<<endl;
return 0;
}
又或者
#include<bits/stdc++.h>
#define maxn 500010
#define re register
#define FOR(i,l,r) for(re int i=l;i<=r;++i)
using namespace std;
int n,m,c,r,t,x,y,z,sq,anss;
int a[maxn],b[maxn],tag[maxn],ans[maxn];
inline void in(int &x){
x=0;char c=getchar();
while(c<'0'||c>'9'){
c=getchar();
}
while(c<='9'&&c>='0'){
x=(x<<1)+(x<<3)+(c^'0');
c=getchar();
}
}
inline void out(int a){
if(a>=10)out(a/10);
putchar(a%10+'0');
}
void doit(int x,int y){
if(tag[b[x]]!=1)
FOR(i,x,min(y,b[x]*sq))
ans[b[x]]-=a[i],a[i]=0;
if(b[x]!=b[y]&&tag[b[y]]!=1)
FOR(i,(b[y]-1)*sq+1,y)
ans[b[y]]-=a[i],a[i]=0;
FOR(i,b[x]+1,b[y]-1)
tag[i]=1,ans[i]=0;
}
int main(){
in(n),in(m);
sq=sqrt(n);
FOR(i,0,n)
a[i]=1,b[i]=(i-1)/sq+1,++ans[b[i]];
FOR(i,1,m){
in(x),in(y);
doit(x,y);
}
FOR(i,1,b[n])
anss+=ans[i];
out(anss);
puts("");
return 0;
}
此段就不解释了,小编客们自己尝试理解吧!
这篇是本人在CSDN上的第一篇文章,希望多多包容!
拜BAI!