「这是我参与2022首次更文挑战的第29天,活动详情查看:2022首次更文挑战」
今天要说的主要是一个蓝桥杯的题目。
题目
题目上说是那个贪心,但是我没想到那个什么贪心,解法。最后是用二分法求解的。 看题目的意思其实很简单,拿出偶数个连续的石头,然后满足那个质量关系,之后我们直接创建一个sum数组 那么问题就变成了,找一个有序数组当中对称部分的差小于或者等于S的问题。
问题分析
竟然我们转化了这个问题,那么现在来分析一下如何处理,很容易想到的就是那个二分法,如果右边的差值大,那么在中间往右不存在那个S,然后缩小范围,之后解答。我们只需要在运行程序的时候注意代码判断边界即可。
之后是那个输入问题,那个数量大,并且直接使用int越界。
所以注意使用long即可
编码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import java.util.StringTokenizer;
class Main {
static int N;
static long S;
static long[] Stones;
static long[] StonesSumWeight;
public static void main(String[] args) throws IOException {
Reader.init(System.in);
N = Reader.nextInt();
S = Reader.nextLong();
//从下标1开始方便我找元素,此外为了避免重复运算先计算所有的质量和
Stones = new long[N + 1];
StonesSumWeight = new long[N + 1];
for(int i=1;i<=N;i++){
Stones[i]=Reader.nextLong();
StonesSumWeight[i] = StonesSumWeight[i-1]+Stones[i];
}
//我们题目要求的是2*k个石头,其实就是偶数
//问题变成了我们在StoneSunWeight里面找到左右两边的差值不大于S的,如果没有
//找到那个差值说明太大了,所以直接缩短一般距离。
int left = 1;
int right = N;
while (left<right){
int mid = (right+left+1)>>1;
if(IsFun(mid)){
left = mid;
}else{
right = mid-1;
}
}
System.out.println(2*left);
}
private static boolean IsFun(int mid) {
for(int i = mid; i <= (N - mid); i++) {
if(StonesSumWeight[i] - StonesSumWeight[i - mid] <= S && StonesSumWeight[i + mid] - StonesSumWeight[i] <= S) {
return true;
}
}
return false;
}
}
class Reader {
static BufferedReader reader;
static StringTokenizer tokenizer;
/**
* call this method to initialize reader for InputStream
*/
static void init(InputStream input) {
reader = new BufferedReader(
new InputStreamReader(input));
tokenizer = new StringTokenizer("");
}
/**
* get next word
*/
static String next() throws IOException {
while (!tokenizer.hasMoreTokens()) {
//TODO add check for eof if necessary
tokenizer = new StringTokenizer(
reader.readLine());
}
return tokenizer.nextToken();
}
static int nextInt() throws IOException {
return Integer.parseInt(next());
}
static long nextLong() throws IOException{
return Long.parseLong(next());
}
static double nextDouble() throws IOException {
return Double.parseDouble(next());
}
}