又到了丰收的季节,恰逢小易去牛牛的果园里游玩。
牛牛常说他对整个果园的每个地方都了如指掌,小易不太相信,所以他想考考牛牛。
在果园里有N堆苹果,每堆苹果的数量为ai,小易希望知道从左往右数第x个苹果是属于哪一堆的。
牛牛觉得这个问题太简单,所以希望你来替他回答。
第一行一个数n(1 <= n <= 105)。
第二行n个数ai(1 <= ai <= 1000),表示从左往右数第i堆有多少苹果
第三行一个数m(1 <= m <= 105),表示有m次询问。
第四行m个数qi,表示小易希望知道第qi个苹果属于哪一堆。
m行,第i行输出第qi个苹果属于哪一堆。
5 2 7 3 4 9 3 1 25 11
1 5 3
import java.util.*; public class Main{ public static void main(String[] args){ Scanner sc=new Scanner(System.in); TreeMap<Integer,Integer> map=new TreeMap<>(); int sum=0; int count=0; while(sc.hasNext()){ int n=sc.nextInt(); for(int i=0;i<n;i++){ int a=sc.nextInt(); count++; sum+=a; map.put(sum,count); } int m=sc.nextInt(); for(int i=0;i<m;i++) System.out.println(map.get(map.ceilingKey(sc.nextInt()))); } sc.close(); } }
import java.util.Scanner; public class Main { public static void main (String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] arr1 = new int[n]; int[] arr2 = new int[n]; int pre = 0; for (int i = 0; i < n; i++) { arr1[i] = sc.nextInt(); pre += arr1[i]; arr2[i] = pre; } int m = sc.nextInt(); for (int i = 0; i < m; i++) { int q = sc.nextInt(); nadui(arr2, q); } } public static void nadui(int[] arr, int index) { // 顺序查找超时 // 改为二分查找 if (index <= arr[0]) { System.out.println(1); return; } int begin = 0; int end = arr.length-1; int m = (begin + end)/2; while (end - begin > 1) { if (index > arr[m]) { begin = m; m = (begin + end)/2; } else { end = m; m = (begin + end)/2; } } System.out.println(end+1); } }
import java.io.*; public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(br.readLine()); String[] line1 = br.readLine().split(" "); int m = Integer.parseInt(br.readLine()); String[] line2 = br.readLine().split(" "); int[] ah = new int[n]; ah[0] = Integer.parseInt(line1[0]); for (int i = 1; i < n; i++) { ah[i] = Integer.parseInt(line1[i]) + ah[i - 1]; } StringBuilder sb = new StringBuilder(); for (int i = 0; i < m; i++) { int target = Integer.parseInt(line2[i]); int l = 0, r = n - 1; while (l < r) { int mid = l + (r - l) / 2; if (ah[mid] < target) { l = mid + 1; } else { r = mid; } } sb.append(l + 1).append("\n"); } System.out.print(sb.toString()); } }java 二分查找
我使用TreeMap成功之后,发现一个问题,有时候提交能够过,有时候提交会超时,是网的问题吗?好奇怪 import java.util.*; public class Main{ public static void main(String[]args){ int n,m; Scanner in=new Scanner(System.in); n=in.nextInt(); int[]storage=new int[n]; int sum=0; TreeMap<Integer,Integer>heap=new TreeMap<>(); for(int i=0;i<n;i++){ storage[i]=in.nextInt(); heap.put(sum+1,i+1); sum+=storage[i]; } m=in.nextInt(); int[]judge=new int[m]; for(int i=0;i<m;i++){ judge[i]=in.nextInt(); if(judge[i]>sum){ System.out.println(-1); continue; } System.out.println(heap.get(heap.floorKey(judge[i]))); } } }
import java.util.Scanner; import java.util.Arrays; //菜鸟一个,利用二分查找AC成功,需要注意的是不要导入全部java包,不然会超时。 public class Main{ public static void main(String[] args){ Scanner sc = new Scanner(System.in); int n = sc.nextInt();//输入苹果堆数 int sum = 0; int[] a = new int[n];//存放每堆苹果数量 for(int i = 0; i < n; i++){ int apple = sc.nextInt(); a[i] = sum + apple;//将每堆苹果以累加的方式存放 形成一个有序不重复数组 sum = a[i]; } int m = sc.nextInt();//输入询问次数 int[] q = new int[m]; for(int i = 0; i < m; i++){ q[i] = sc.nextInt();//存放每次询问苹果的数量 } //利用java的binarySearch(object[ ], object key)方法 //返回值:如果key在数组中,则返回搜索值的索引,从0开始计数; //否则返回-1或者”-“(插入点)。插入点是索引键将要插入数组的那一点,即第一个大于该键的元素索引,从1开始计数。 for(int i = 0; i < m; i++){ int index = Arrays.binarySearch(a, q[i]); if(index > 0){//索引大于0,表示找到相同元素,因为是从0开始,所以加1 System.out.println(index + 1); }else{//索引小于0,就是-1或者”-“(插入点)的情况,直接取反 System.out.println(-index); } } } }
import java.util.Scanner; public class Main{ static class AppleHeap{ int appleNum = 0; int heapNum = 0; AppleHeap(int appleNum, int heapNum){ this.appleNum = appleNum; this.heapNum = heapNum; } } public static void main(String [] args){ Scanner sc = new Scanner(System.in); int n = sc.nextInt(); AppleHeap [] appleHeaps= new AppleHeap[n]; appleHeaps[0] = new AppleHeap(sc.nextInt(),1); for(int i = 1; i < n; i++){ appleHeaps[i] = new AppleHeap(appleHeaps[ i - 1].appleNum + sc.nextInt(),i + 1); } int m = sc.nextInt(); int [] ask = new int[m]; for(int i = 0; i < m; i++){ ask[i] = sc.nextInt(); } for(int i = 0; i < m; i++){ System.out.println(find(appleHeaps, ask[i])); } } //二分查找 private static int find(AppleHeap [] appleHeaps, int num){ int low = 0, high = appleHeaps.length, mid = 0; while(low <= high){ mid = low + (high - low) / 2; if(appleHeaps[mid].appleNum < num){ low = mid + 1; }else if(appleHeaps[mid].appleNum > num){ high = mid - 1; }else { return appleHeaps[mid].heapNum; } } if(appleHeaps[mid].appleNum > num){ return appleHeaps[mid].heapNum; }else { return appleHeaps[mid].heapNum + 1; } } }
import java.util.*; public class Main{ public static void main(String[] args){ Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); int[] sum = new int[n]; for (int i = 0;i < n;i ++){ if (i == 0) sum[i] = scanner.nextInt(); else sum[i] = sum[i - 1] + scanner.nextInt(); } int m = scanner.nextInt(); for (int i = 0;i < m;i ++){ System.out.println(erfen(0,n - 1,sum,scanner.nextInt())); } } private static int erfen(int start,int end,int[] num,int target){ while(start < end) { int mid = (start + end) >> 1; if (num[mid] == target) { return mid + 1; }else if(num[mid] < target){ start = mid + 1; }else { end = mid - 1; if (end >= 0) { if (num[end] < target) { return end + 2; } } } } return start + 1; } }就是一个二分查找 把 加号换成位运算就过了
一个简单的二分
import java.util.*; public class Main{ public static void main(String[] args){ Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int a[] = new int[n]; a[0] = sc.nextInt(); for(int i=1;i<n;i++){ a[i] = a[i-1]+sc.nextInt(); } int m = sc.nextInt(); int[] q = new int[m]; for(int i=0;i<m;i++){ q[i] = sc.nextInt(); } for(int i=0;i<m;i++){ int left=0,right=n-1; while(left+1!=right){ int mid = (left+right)>>1; if(q[i]<=a[mid])right=mid; else left=mid; } System.out.println(q[i]>a[left]?right+1:left+1); } } }
public static void main(String[] args) {
// 开始录入数据
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int[] a = new int[n];
int[] temp = new int[n];
int sum = 0;
for (int i = 0; i < n; i++) {
a[i] = scanner.nextInt();
sum += a[i];
temp[i] = sum;
}
int m = scanner.nextInt();
int q[] = new int[m];
for (int i = 0; i < m; i++) {
q[i] = scanner.nextInt();
}
// 录入数据结束,开始查找
int start, end, mid;
boolean flag = false;
for (int i = 0; i < m; i++) {
flag = false;
start = 0; end = n - 1; mid = 0;
//折半
while (start <= end) {
mid = start + (end - start) / 2;
if (q[i] == temp[mid]) {//恰好找到
System.out.println(mid + 1);
flag = true;
break;
} else if (q[i] < temp[mid])
end = mid - 1;
else if (q[i] > temp[mid])
start = mid + 1;
}
if (flag)
continue;
System.out.println(1 + Math.max(start, end));
}
}