poj3061 二分前缀和+尺取法

版权声明:点个关注(^-^)V https://blog.csdn.net/weixin_41793113/article/details/88386573

描述

给出N个正整数(10 <N <100 000)的序列,每个正整数小于或等于10000,并且给出正整数S(S <100 000 000)。编写程序以找到序列的连续元素的子序列的最小长度,其总和大于或等于S.

输入

第一行是测试用例的数量。对于每个测试用例,程序必须从第一行读取数字N和S,以间隔分隔。序列的编号在测试用例的第二行中给出,以间隔分开。输入将以文件结尾结束。

输出

对于每种情况,程序必须在输出文件的单独行上打印结果。如果没有答案,则打印0。

样本输入

2
10 15
5 1 3 5 10 7 4 9 2 8
5 11
1 2 3 4 5

样本输出

2
3

原题链接

import java.util.Arrays;
import java.util.Scanner;

public class poj3061 {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int T = in.nextInt();
		while(T-->0) {
			int n = in.nextInt();
			int s = in.nextInt();
			int[] sum = new int[n+1];//前缀和数组
			for(int i=1;i<=n;i++) 
				sum[i] = sum[i-1] + in.nextInt();
			
			if(sum[n]<s) {//所有加起来没s大,肯定不行啊
				System.out.println(0);
				continue;
			}
			int ans = 99999999;
			for(int i=0;sum[n]-sum[i]>=s;i++) {//枚举左指针
				int j = Arrays.binarySearch(sum, i, n+1,sum[i]+s);//二分找右指针
				if(j<0)
					j = -j - 1;
//				System.out.println(i+":"+j);
				ans = Math.min(ans, j-i);
			}
			
			System.out.println(ans);
		}

	}

}

 POJ3061 Subsequence(二分前缀和、尺取法) 

Arrays类里的binarySearch方法的返回值总结

  • 举例原始数组 a 如下:
[3, 5, 8, 17, 12, 2]
  • 第一步:必须先对数组进行排序 Arrays.sort(a) ;,排序后的数组如下:
[2, 3, 5, 8, 12, 17]
  • 如果找到关键字,则返回值为关键字在排序后的数组中的位置索引,且索引从0开始。
  • 如果没有找到关键字,返回值为负的插入点值,所谓插入点值就是第一个比关键字大的元素在数组中的位置索引,而且这个位置索引从1开始。
//结果显示 0
System.out.println(Arrays.binarySearch(a,2)) ;
//结果显示 -3
//4在数据中没有,插入点即是3和5之间,位置索引从1开始数的话,这个位置就是3,取负即为-3
System.out.println(Arrays.binarySearch(a,4)) ;

重点说明:使用binarySearch查找时,务必先排序。

  • 排序后的返回结果是负数就一定说明没找到
  • 不排序的话,即使数组中能找到相关关键字,那也有可以返回负数。

猜你喜欢

转载自blog.csdn.net/weixin_41793113/article/details/88386573