7 区间和
前缀和,注意[a,b]的和为sums[b] - sums[a-1]
, 同时要注意a为0的情况,如果a为0,则[0,b]的区间和为sums[b]
或者统一写成 sums[b] - sums[a] +nums[a]
注意java包的导入,输出和输入,main函数的书写
题目描述
给定一个整数数组 Array,请计算该数组在每个指定区间内元素的总和。
输入描述
第一行输入为整数数组 Array 的长度 n,接下来 n 行,每行一个整数,表示数组的元素。随后的输入为需要计算总和的区间下标:a,b (b > = a),直至文件结束。
输出描述
输出每个指定区间内元素的总和。
输入示例
5
1
2
3
4
5
0 1
1 3
输出示例
3
9import java.util.Scanner;
public class Main{public static void main(String[] args){Scanner sc = new Scanner(System.in);int n = sc.nextInt();int[] nums = new int[n];int[] sums = new int[n];int sum = 0;for(int i=0;i<n;i++){nums[i] = sc.nextInt();sum+=nums[i];sums[i] = sum;}while(sc.hasNextInt()){int a= sc.nextInt();int b=sc.nextInt();System.out.println(sums[b] - sums[a] +nums[a]);}sc.close();}
}
8 开发商购买土地
因为题目横纵切割,所以横纵均为一个前缀和数组
//前缀和
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt();int m = scanner.nextInt();int sum = 0;int[][] vec = new int[n][m];for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {vec[i][j] = scanner.nextInt();sum += vec[i][j];}}// 统计横向int[] horizontal = new int[n];for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {horizontal[i] += vec[i][j];}}// 统计纵向int[] vertical = new int[m];for (int j = 0; j < m; j++) {for (int i = 0; i < n; i++) {vertical[j] += vec[i][j];}}int result = Integer.MAX_VALUE;int horizontalCut = 0;for (int i = 0; i < n; i++) {horizontalCut += horizontal[i];result = Math.min(result, Math.abs(sum - 2 * horizontalCut));}int verticalCut = 0;for (int j = 0; j < m; j++) {verticalCut += vertical[j];result = Math.min(result, Math.abs(sum - 2 * verticalCut));}System.out.println(result);scanner.close();}
}//优化版
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt();int m = scanner.nextInt();int sum = 0;int[][] vec = new int[n][m];for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {vec[i][j] = scanner.nextInt();sum += vec[i][j];}}int result = Integer.MAX_VALUE;int count = 0; // 统计遍历过的行// 行切分for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {count += vec[i][j];// 遍历到行末尾时候开始统计if (j == m - 1) {result = Math.min(result, Math.abs(sum - 2 * count));}}}count = 0;// 列切分for (int j = 0; j < m; j++) {for (int i = 0; i < n; i++) {count += vec[i][j];// 遍历到列末尾时候开始统计if (i == n - 1) {result = Math.min(result, Math.abs(sum - 2 * count));}}}System.out.println(result);scanner.close();}
}