牛客小白月赛15 A斑羚飞渡 (贪心)

题目链接:https://ac.nowcoder.com/acm/contest/917/A

题意:
有n个羊,每只羊可以自己可以跳x[i]米,踩在别的羊身上可以跳y[i]米,每只羊只可以被别的羊踩一次每只羊也可以不被踩或者不踩别的羊。现在要跳过长为s米的峡谷,问最优情况下,有多少只羊可以越过峡谷。
题解:
贪心策略:
如果羊自己可以过,就让他自己过(没必要为了让一只羊过在多浪费一只羊)
如果羊的x[i]+y[i]<s,则表明即使他踩在别的羊身上也过不去。所以直接把这些羊当作跳板(被踩的羊)。这种羊的x[i] 放入a数组中。
如果羊的x[i]+y[i]>=s,则表示他可以踩在别的羊身上过去,只要被踩得羊的x[i]小于等于他自己的x[i]且与y[i]相加大于等于s即可越过峡谷此时则配对成功。这种羊的y[i]放在b数组中。

将a中的值从小到大排列,b中的值从大到小排列,每一个b中的值取找一个能够满足他的最小的a。

因为b中的值都满足x[i]+y[i] >=s,所以只要a[i]+b[j]>=s,那么s-y[i]这个点一定在a[i]和x[i]内,所以b[j]这只羊一定可以踩在a[i]这只羊身上,既可以越过峡谷。

附上AC代码:

#include <bits/stdc++.h>

using namespace std;

#define LL long long
const int maxn=1e6+5;

LL a[maxn],b[maxn];
LL s;
int n,cnta=0,cntb=0;

bool cmp(LL a,LL b)
{
    return a>b;
}

int main()
{
	ios::sync_with_stdio(false);
    cin.tie(0);
   	cout.tie(0);
    cin>>n>>s;
    LL ans=0,x,y;
    for(int i=0;i<n;i++)
    {
        cin>>x>>y;
        if(x>=s) ans++;
        else if(x+y<s) a[cnta++]=x;//不能到达对岸,直接当作跳板
        else b[cntb++]=y;//可以跳到对岸,则计入b中
    }
    sort(a,a+cnta);//从小到大排序
    sort(b,b+cntb,cmp);//从大到小排序
    //贪心:最大的先和最小的配对
    int i=0,j=0;
    for(;i<cnta&&j<cntb;j++)
    {
        LL tmp=b[j];
        while(i<cnta)
        {
            //因为保证了b可以过即x+y>=s,所以如果y+a[i]>=s,那么x一定和a[i]有交集且保证在那个点跳跃可以飞过峡谷
            if(tmp+a[i]>=s)//如果第bj个踩在第ai个上可以过,则数量加一
            {
                ans++;
                i++;
                break;
            }
            else
            i++;
        }
    }
    if(j==cntb)//如果可以飞过峡谷的都配对完了,那么直接输出结果
        cout<<ans;
    else//如果没有配对玩,则直接两两配对
        cout<<ans+(cntb-j)/2;

	return 0;
}

欢迎评论!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值