牛客小白月赛-环上食虫


title: 牛客小白月赛-环上食虫
tags:

  • 双指针
  • 环问题
    abbrlink: 2acc60b6
    date: 2022-06-21 16:25:27

题目来源

链接:https://ac.nowcoder.com/acm/contest/11229/D
来源:牛客网

题目描述

牛牛参加了牛妹的派对。
牛牛面前有一个圆桌,圆桌边缘按顺序摆上了 n 个蛋糕(第一个蛋糕和第 n个蛋糕相邻)。
每个蛋糕都有一个饱腹值和奶油含量。
牛牛不喜欢吃奶油,所以他想要在保证自己能吃饱(所吃蛋糕的饱腹度的和大于等于 sss)的情况下,所选择的蛋糕中奶油含量最大的那一个的奶油含量越低越好。我们知道,牛牛一直都是个绅士。所以他选择的蛋糕应该是相邻的(也就是对应圆上的一段弧(也可以是整个圆))。
现在它想请你帮它计算在能够吃饱的情况下,他吃到蛋糕中奶油含量最高的那一个最低会是多少?

输入描述:

输入共三行。
第一行两个正整数 n,s 。
接下来的一行 n 个整数 a1...a代表第一个到第 n 个蛋糕每个蛋糕的饱腹值。

接下来的一行 n个整数 b1...bn 代表第一个到第 n 个蛋糕每个蛋糕的奶油含量。
保证:1≤n≤2×105;   1≤s≤109;   1≤ai,bi≤109 (1≤i≤n);

输出描述:

输出共一行代表答案。
特别的,若牛牛吃掉所有蛋糕都无法吃饱                     

输入

5 9
4 3 7 6 1
1 3 9 2 5

输出

5

说明

选择第 1,2,4,5 个蛋糕:
    饱腹值:4+3+6+1=14>9

    最大奶油含量:max⁡{1,3,2,5}=5

所以输出 5。

算法解析

本题使用算法为,环形问题 + 双指针

环形问题

因为牛牛是只吃旁边的蛋糕,而且蛋糕排列呈现环形,我们可以定义大小为 2*n 的数组来进行环形处理。这样无论牛牛从那个蛋糕开始吃,我们都能让这个蛋糕数组的后面有其它所有蛋糕的数据。

双指针

分析题目可知,我们要在吃的饱的情况下,找到他吃到蛋糕中奶油含量最高的那一个最低(若不理解可以看题目说明)会是多少?

每个蛋糕的最大奶油含量为1<=b<=10^9,那我们只要在这个范围内进行双指针判定就可以拉,通过双指针定位可以以满足条件的奶油含量。

笔者代码

import java.util.HashSet;
import java.util.Scanner;

public class Main {
	static int[] arr ; 
	static int[] v ;
	static int s,n;
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		n = scanner.nextInt();
		s = scanner.nextInt();
		long sum = 0 ;
		
		arr = new int [n*2+1]; 
		v = new int [n*2+1]; 
		
		for(int i = 0;i<n;i++){
			arr[i] = scanner.nextInt();
			arr[i+n] = arr[i];
			sum +=arr[i];
		}
		
		for(int i =0;i<n;i++){
			v[i] = scanner.nextInt();
			v[i+n] = v[i];
		}

		//当所有的蛋糕加起来少于,能够吃饱的总量则返回-1
		if(sum<s){
			System.out.println("-1");
            return;
		}
		
		//使用二分法测算符合范围的奶油的可能
		//题目要求为:所选择的蛋糕中奶油含量最大的那一个的奶油含量越低越好
		int l = 1,r = (int) (1e9+10);
		while(l<r){
			int mid = (l+r)>>1;
			if(check(mid)){
				r =mid;
			}else {
				l = mid+1;
			}
		}
		//找到了在符合吃饱要求的情况下,吃到含奶油最多的蛋糕的最小情况
		System.out.println(l);
	}
	
	public static boolean check(int ans){
		long eatcake = 0;
		for(int i = 0;i<2*n;i++){
			//如果有奶油的量,比当前的猜测奶油量还大,就不符合最蛋糕大奶油猜测,
			//说明不能像这样连续吃,则重新开始吃
			if(v[i]>ans){
				eatcake = 0;
			}else {
				eatcake+=arr[i];
				//已经能够吃饱,并且奶油量符合范围
				if(eatcake>=s){
					return true;
				}
			}
		}
		return false;
	}

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值