AcWing寒假每日一题——Day8校门外的树

校门外的树

某校大门外长度为 L L L的马路上有一排树,每两棵相邻的树之间的间隔都是 1 1 1米。

我们可以把马路看成一个数轴,马路的一端在数轴 0 0 0的位置,另一端在 L L L的位置;数轴上的每个整数点,即 0 , 1 , 2 , … … , L , 0,1,2,……,L, 0,1,2,……,L,都种有一棵树。

由于马路上有一些区域要用来建地铁。

这些区域用它们在数轴上的起始点和终止点表示。

已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。

现在要把这些区域中的树(包括区域端点处的两棵树)移走。

你的任务是计算将这些树都移走后,马路上还有多少棵树。

输入格式
输入文件的第一行有两个整数 L L L和 M , L M,L M,L代表马路的长度, M M M代表区域的数目, L L L和 M M M之间用一个空格隔开。

接下来的 M M M行每行包含两个不同的整数,用一个空格隔开,表示一个区域的起始点和终止点的坐标。

输出格式
输出文件包括一行,这一行只包含一个整数,表示马路上剩余的树的数目。

数据范围
1 ≤ L ≤ 10000 , 1≤L≤10000, 1≤L≤10000,
1 ≤ M ≤ 100 1≤M≤100 1≤M≤100
输入样例:

500 500 500 3 3 3
150 150 150 300 300 300
100 100 100 200 200 200
470 470 470 471 471 471

输出样例:

298 298 298

分析: 此题一看就是区间合并问题,不过也可以用暴力的做法做

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
bool a[N];
int main(){
    int l,m,i,j,sum=0,left,right;
    cin>>l>>m;
    for(i=0;i<m;i++){
        cin>>left>>right;
        for(j=left;j<=right;j++){
            a[j]=1;
        }
    }
    for(i=0;i<=l;i++){
        if(a[i]==0){
            sum++;
        }
    }
    cout<<sum<<endl;
}

也可以用差分优化一下:

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
bool a[N];
int b[N];
int main(){
    int l,m,i,j,sum=0,left,right;
    cin>>l>>m;
    for(i=0;i<m;i++){
        cin>>left>>right;
        b[left]++;
        b[right+1]--;
    }
    for(i=0;i<=l;i++){
        b[i]+=b[i-1];
        if(b[i]==0){
            sum++;
        }
    }
    cout<<sum<<endl;
}

优化算法:区间合并,我以前发过文章:区间合并

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
struct node{
    int l,r;
}a[N],b[N];
bool cmp(node a,node b){
    return a.l<b.l;
}
int main(){
    int l,m,i;
    cin>>l>>m;
    for(i=0;i<m;i++){
        cin>>a[i].l>>a[i].r;
    }
    sort(a,a+m,cmp);
    int right=a[0].r,left=a[0].l,ans=1,sum=0;
    b[ans].l=left,b[ans].r=right;
    for(i=1;i<m;i++){
        if(a[i].l>right){
            b[ans].l=left;
            b[ans].r=right;
            ans++;
            left=a[i].l;
            right=a[i].r;
        }
        else{
            right=max(right,a[i].r);
            b[ans].r=right;
        }
    }
    b[ans].l=left;
    b[ans].r=right;
    for(i=1;i<=ans;i++){
        sum+=b[i].r-b[i].l+1;
    }
    cout<<l-sum+1<<endl;
}
上一篇:day8-字符串作业


下一篇:Java基础学习 Day8 (流程控制)