zoukankan      html  css  js  c++  java
  • 一本通1423 种树

     

     这道题是一个典型的区间选点问题。每一个房子代表一个要求,这个要求对应着一个左端点和右端点,以及一个要求的树数。它就相当于是给定一个区间,在这个区间内插入要求的点数。求的种数的最小数量即为总点数。

    这样我们就可以将这个问题转化为一个区间选点问题并得出基本思路。

    基本思路:种树要种得少,就要尽量让一棵树处在多个区间内。这样,我们只需要尽量在重叠区间种树即可。而重叠部分一定位于区间尾部。因此,我们可以先按照所有区间的结束位置进行排序,之后依次处理每一个区间,先在一个区间的尾部种满足够的树,对下一个区间,只需要判断还需要多少棵树就在区间的尾部中多少就可以

    下面写代码。

    首先我们需要定义好需要的变量。定义n表示区域个数,m表示房子的数目,ans表示种树的最小数量,同时开一个i方便输入。

    同时我们需要定义一个结构体来存储每一个种树的需求。设l表示需求的左边界,r表示需求的右边界,need表示需要的树的数量,然后进行输入输出。

    得出代码如下:

     1 #include<iostream>
     2 using namespace std;
     3 int n,m,i,ans; 
     4 struct xuqiu{
     5     int l;
     6     int r;
     7     int need;
     8 }t[5005];
     9 int main(){
    10     cin>>n>>m;
    11     for(i=1;i<=m;i++){
    12         cin>>t[i].l>>t[i].r>>t[i].need;
    13     }
    14     return 0;
    15 }

    接下来按照我们的思路,我们需要按照所有需求的右边界进行一遍排序,方便后续将树从小到大进行插入。这里需要手写cmp函数。

    得出代码如下:

     1 #include<iostream>
     2 #include<algorithm>
     3 using namespace std;
     4 int n,m,i,ans;
     5 struct xuqiu{
     6     int l;
     7     int r;
     8     int need;
     9 }t[5005];
    10 bool cmp(xuqiu a,xuqiu b){
    11     if(a.r<b.r){
    12         return true;
    13     }else{
    14         return false;
    15     }
    16 }
    17 int main(){
    18     cin>>n>>m;
    19     for(i=1;i<=m;i++){
    20         cin>>t[i].l>>t[i].r>>t[i].need;
    21     }
    22     sort(t+1,t+m+1,cmp);
    23     return 0;
    24 }

    然后我们就要进入主要的环节了。首先,我们需要对ans进行初始化。为了方便,我们要开一个bool数组used来表示该点是否已经种上了树,其中true表示该点已有树,false表示该点没有树。然后我们枚举每一个需求,并设置一个新变量k来表示当前这个需求的区间里已有多少棵树。我们开一个变量j来对这个需求的区间进行枚举,先记录下已有的树的数量。如果已有树的数量大于等于所需树的数量,该要求已经满足,可以将它continue掉,否则从右边界向左边界进行枚举,判断如果该点没有种过树,就种上树。直到树的数目足够为止。最后将答案输出即可。

    下面是完整代码(含注释):

     1 #include<iostream>
     2 #include<algorithm>
     3 using namespace std;
     4 int n,m,i,j,k,ans;
     5 bool used[30005]={0};//记录该位置是否有树,有为true,没有为false 
     6 struct xuqiu{
     7     int l;
     8     int r;
     9     int need;
    10 }t[5005];
    11 bool cmp(xuqiu a,xuqiu b){
    12     if(a.r<b.r){
    13         return true;
    14     }else{
    15         return false;
    16     }
    17 }
    18 int main(){
    19     cin>>n>>m;
    20     for(i=1;i<=m;i++){
    21         cin>>t[i].l>>t[i].r>>t[i].need;
    22     }
    23     sort(t+1,t+m+1,cmp);
    24     ans=0;//记录树的总数
    25     for(i=1;i<=m;i++){
    26         k=0;
    27         for(j=t[i].l;j<=t[i].r;j++){
    28             if(used[j]==true){//记录这个需求的左边界到右边界内已有树的数目 
    29                 k++;
    30             }
    31         }
    32         if(k>=t[i].need){//树的数目足够
    33             continue;
    34         }
    35         for(j=t[i].r;j>=t[i].l;j--){//否则从右向左进行种树
    36             if(used[j]==false){//如果这个地方没有种过树 
    37                 used[j]=true;
    38                 k++;
    39                 ans++;//多种了一棵树
    40             }
    41             if(k==t[i].need){//达到了树的需求量
    42                 break;
    43             }
    44         }
    45     }
    46     cout<<ans<<endl;
    47     return 0;
    48 }

    这样这道题就通过了。

  • 相关阅读:
    阿里IM技术分享(六):闲鱼亿级IM消息系统的离线推送到达率优化
    IM开发基础知识补课(十):大型IM系统有多难?万字长文,搞懂异地多活!
    长连接网关技术专题(六):石墨文档单机50万WebSocket长连接架构实践
    手把手教你实现网页端社交应用中的@人功能:技术原理、代码示例等
    跟着源码学IM(九):基于Netty实现一套分布式IM系统
    网络编程懒人入门(十三):一泡尿的时间,快速搞懂TCP和UDP的区别
    探探的IM长连接技术实践:技术选型、架构设计、性能优化
    直播系统聊天技术(六):百万人在线的直播间实时聊天消息分发技术实践
    基于实践:一套百万消息量小规模IM系统技术要点总结
    Datafram 实现作为正文发送邮件
  • 原文地址:https://www.cnblogs.com/qianr/p/13284156.html
Copyright © 2011-2022 走看看