洛谷 P1697 [USACO18JAN] Lifeguards B 题解

题目描述

Farmer John has opened a swimming pool for his cows, figuring it will help them relax and produce more milk.

To ensure safety, he hires N cows as lifeguards, each of which has a shift that covers some contiguous interval of time during the day. For simplicity, the pool is open from time t=0 until time t=1000 on a daily basis, so each shift can be described by two integers, giving the time at which a cow starts and ends her shift. For example, a lifeguard starting at time t=4 and ending at time t=7 covers three units of time (note that the endpoints are "points" in time).

Unfortunately, Farmer John hired 1 more lifeguard than he has the funds to support. Given that he must fire exactly one lifeguard, what is the maximum amount of time that can still be covered by the shifts of the remaining lifeguards? An interval of time is covered if at least one lifeguard is present.

输入格式

The first line of input contains N(1≤N≤100). Each of the next N lines describes a lifeguard in terms of two integers in the range0…1000, giving the starting and ending point of a lifeguard's shift. All such endpoints are distinct. Shifts of different lifeguards might overlap.

输出格式

Please write a single number, giving the maximum amount of time that can still be covered if Farmer John fires 1 lifeguard.

题意翻译

给定 n 个左闭右开区间,问在去掉任意一个区间的情况下,区间的覆盖长度最大是多少。

输入输出样例

输入 #1

3
5 9
1 4
3 7

输出 #1

7

思路:

由于数据范围较小,可以定义一个vis数组,vis[i]代表i那里有没有被覆盖(看的翻译),然后直接暴力,三层循环枚举,具体方法如下:

1.定义一个结构体,代表每个区间的起始位置和终止位置(又看的翻译,前面应该说的是救生员吧,我也是看别人的才知道具体意思的,毕竟我一个5年级小学生怎么看的懂这个),再定义一个ans代表最终答案

2.读入数据(不用多说),温馨提示:我喜欢下标从0开始,如果你喜欢从1开始,下面也有

3.三层循环:

        第1层:0到n-1的循环,什么意思要我说吗?

                      定义一个cnt=0,表示这一轮区间的覆盖长度(还是看了翻译

                      第2层:先初始化vis数组全部为0(注意要从0到1000,不是从0到n!!!

                     从0枚举到n-1,如果j(第二层循环变量)= i(第一层循环变量)直接continue重来

                               第3层:从a[j].start(开始位置)枚举到a[j].finish(结束位置),vis[k]=1

                      从0枚举到1000,如果vis[i]=1的话cnt++

                       比较cnt和ans(有3种写法,下面代码里有)—

         输出ans即可

(由于前面有思路分析,代码里不写了)

AC代码1(下标0):

#include<bits/stdc++.h>
using namespace std;
struct Node
{
    int start,finish;
}a[105];
bool vis[1005];
int main()
{
    int n,ans=INT_MIN;
    cin >> n;
    for(int i=0;i<n;i++)
    {
        cin >> a[i].start >> a[i].finish;
    }
    for(int i=0;i<n;i++)
    {
        int cnt=0;
        for(int j=0;j<=1000;j++)
        {
            vis[j]=0;
        }
        for(int j=0;j<n;j++)
        {
            if(j==i)
            {
                continue;
            }
            for(int k=a[j].start;k<a[j].finish;k++)
            {
                vis[k]=1;
            }
        }
        for(int j=0;j<=1000;j++)
        {
            if(vis[j])
            {
                cnt++;
            }
        }
        ans=cnt>=ans?cnt:ans;
    }
    cout<<ans;
    return 0;
}

AC提交记录:下标0 

AC代码2(下标1):

#include<bits/stdc++.h>
using namespace std;
struct Node
{
    int start,finish;
}a[105];
bool vis[1005];
int main()
{
    int n,ans=INT_MIN;
    cin >> n;
    for(int i=1;i<=n;i++)
    {
        cin >> a[i].start >> a[i].finish;
    }
    for(int i=1;i<=n;i++)
    {
        int cnt=0;
        for(int j=0;j<=1000;j++)
        {
            vis[j]=0;
        }
        for(int j=1;j<=n;j++)
        {
            if(j==i)
            {
                continue;
            }
            for(int k=a[j].start;k<a[j].finish;k++)
            {
                vis[k]=1;
            }
        }
        for(int j=0;j<=1000;j++)
        {
            if(vis[j])
            {
                cnt++;
            }
        }
        ans=cnt>=ans?cnt:ans;
    }
    cout<<ans;
    return 0;
}

AC提交记录:下标1

好,最后就给你们看一下那3种写法:

#include<bits/stdc++.h>
using namespace std;
struct Node
{
    int start,finish;
}a[105];
bool vis[1005];
int main()
{
    int n,ans=INT_MIN;
    cin >> n;
    for(int i=1;i<=n;i++)
    {
        cin >> a[i].start >> a[i].finish;
    }
    for(int i=1;i<=n;i++)
    {
        int cnt=0;
        for(int j=0;j<=1000;j++)
        {
            vis[j]=0;
        }
        for(int j=1;j<=n;j++)
        {
            if(j==i)
            {
                continue;
            }
            for(int k=a[j].start;k<a[j].finish;k++)
            {
                vis[k]=1;
            }
        }
        for(int j=0;j<=1000;j++)
        {
            if(vis[j])
            {
                cnt++;
            }
        }
        ans=cnt>=ans?cnt:ans;//写法1,三元表达式
        ans=max(cnt,ans);//写法2:max函数
        if(cnt>ans)
        {
            ans=cnt;
        }//写法3:分支结构(和三元表达式本质一样,就是有点长
    }
    cout<<ans;
    return 0;
}

如果想了解三元表达式什么的,建议去网上搜一下,我这里就不提了(之前提过的,而且主要是我也没学过

OK,这篇博客就到这里啦,我们下篇博客见!(点个赞吧点个赞吧点个赞吧点个赞吧点个赞吧

                      

  • 19
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值