由于区间有重叠,所以我们将区间作为一个结构体
struct region{ int from; int to; }r[105];
from是区间的起点,to为区间终点。r是一个region的数组。
我们按照区间from由小到大的顺序,将区间排序。比如输入的区间为 300 340;120 310;1 10
排完顺序后的排列为:1 10;120 310;300 340。我们维持一个begin和一个end,这两个变量分别是连续区间的最左边和最右边。
遍历此时排列好的区间,如果此时的区间from在begin和end之间,这说明,这个区间与之间的区间有重叠。此时需要比较这个区间的to与end的大小,如果to>end,则end=to;
如果from并不在begin和end之间,则说明这个区间与之前维持的大区间并不连续,没有重叠,这时,我们只需用剩下的树的个数-之间的区间的的树。同时将begin和end赋值为当前区间的from和to。
直到遍历到最后一个区间,此时直接用剩下的树个数-当前维护的大区间里的树,即可。
#include <iostream> #include <algorithm> /* run this program using the console pauser or add your own getch, system("pause") or input loop */ using namespace std; struct region{ int from; int to; }r[105]; int l=10005; int m=105; bool cmp(region a,region b){ if(a.from!=b.from) return a.from<b.from; } int end1; int begin1; int tree; int main(int argc, char** argv) { while(scanf("%d%d",&l,&m)!=EOF){ for(int i=0;i<m;i++){ scanf("%d%d",&r[i].from,&r[i].to); } sort(r,r+m,cmp); end1=r[0].to; begin1=r[0].from; tree=l+1; for(int i=0;i<m;i++){ if(i==(m-1)){ tree-=(end1-begin1+1); } else{ if((begin1<=r[i+1].from)&&(r[i+1].from<=end1)){ if(r[i+1].to>end1){ end1=r[i+1].to; } } else{ tree-=(end1-begin1+1); begin1=r[i+1].from; end1=r[i+1].to; } } } printf("%d\n",tree); } return 0; }
其中我们需要注意的是结构体排序的写法。
这里我用的是sort函数,这个函数的用法为sort(a,a+n)//a是数组的名字,n是长度,sort默认从大到小排序。
如果自己定义的话:sort(a,a+n,cmp)cmp是个函数,里面定义了自己要实现的排序方式,如:
bool cmp(region a,region b){
return a.from<b.from;
}