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;
}
}