Codeforces - 363B. Fence & 466C. Number of Ways

版权声明:版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zxzxzx0119/article/details/85477653

Codeforces - 363B. Fence & 466C. Number of Ways


Codeforces - 363B - Fence

题目链接

题目大意

就是给你一个n、k,然后给你n个数,要你在n个数中求最小的k个数的和,这k个数必须是连续的。

在这里插入图片描述

解析

思路:

  • 先求前k个数的和,然后类似和滑动窗口一样;
  • 用两个指针,第一个i指向窗口的左边,另一个j指向窗口的右边,然后每次左边去掉一个数,右边加上一个数,然后计算新的和,看是否更小,如果更小,更新即可;
import java.io.BufferedInputStream;
import java.util.Scanner;

public class Main {

    public static void main(String[] args){
        Scanner cin = new Scanner(new BufferedInputStream(System.in));
        int n = cin.nextInt();
        int k = cin.nextInt();
        int[] arr = new int[n];
        for(int i = 0; i < n; i++)
            arr[i] = cin.nextInt();

        int sum = 0;
        for(int i = 0; i < k; i++) // 先计算前k个数
            sum += arr[i];

        int minn = sum;
        int mini = 0;
        for(int i = 0, j = k; j < n ; i++, j++ ){ //然后每次前面减去一个数,后面加上一个数,看是否有更小的k个数
            sum = sum-arr[i]+arr[j];
            if(sum < minn){
                minn = sum;
                mini = i+1;
            }
        }
        System.out.println(mini + 1);
    }
}

Codeforces - 466C - Number of Ways

题目链接

题目大意

就是给你一个数组,要将这个数组分成和相等的三个部分,问你有多少种分法。

在这里插入图片描述

解析

这题没做出来,完整的题解在这里。解法很奇妙:

  • 首先计算出每个位置的前缀和sums[i],整个数组的和存在sums[n-1]中;
  • 因为要分成三部分,所以sums[n-1] % 3一定要等于0,不然就没有解,输出0即可;
  • 然后就遍历整个数组,记sums[n-1]/3 = avg,看sums[i] == avgsums[i] == 2 * avg的位置,然后使用两个变量rescnt统计,其中的玄机也是很巧妙。统计的顺序可以从n-2 ~ 0,也可以从0 ~ n-2(n-1是第三个部分,不要算进去)。看两个例子就能体会到了。。

在这里插入图片描述

注释部分是从n-2 ~ 0,非注释部分是从0 ~ n-2:

import java.io.BufferedInputStream;
import java.util.Scanner;

public class Main {

    public static void main(String[] args){
        Scanner cin = new Scanner(new BufferedInputStream(System.in));
        int n = cin.nextInt();
        int[] arr = new int[n];
        for(int i = 0; i < n; i++)
            arr[i] = cin.nextInt();
        long[] sums = new long[n];
        sums[0] = arr[0];
        for(int i = 1; i < n; i++)
            sums[i] = sums[i-1] + arr[i];
        // each part is S/3
        if(sums[n-1]%3 != 0){
            System.out.println(0);
            return;
        }
        long avg = sums[n-1]/3;
        long cnt = 0, res = 0;
//        for(int i = n-2; i >= 0; i--){ // 必须从n-2开始,从n-1会出错,因为n-1是第3个S/3了
//            if(sums[i] == avg)  // 这个必须在下面cnt+=1之前
//                res += cnt;
//            if(sums[i] == avg*2)
//                cnt += 1;
//        }
        for(int i = 0; i < n-1; i++){ // 必须只能到n-2,到n-1会出错,因为n-1是第3个S/3了
            if(sums[i] == avg*2) // 这个必须在下面cnt+=1之前
                res += cnt;
            if(sums[i] == avg)
                cnt += 1;
        }
        System.out.println(res);
    }
}

猜你喜欢

转载自blog.csdn.net/zxzxzx0119/article/details/85477653