首页 > 试题广场 >

喜欢切数组的红

[编程题]喜欢切数组的红
  • 热度指数:9210 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 512M,其他语言1024M
  • 算法知识视频讲解
\hspace{15pt}小红有一个长度为 n 的数组 \{a_1,a_2,\dots,a_n\} ,她打算将数组切两刀变成三个非空子数组,使得每一个子数组中至少存在一个正数,且每个子数组的和都相等。
\hspace{15pt} 看起来不是很难,所以小红想让你求解,一共有多少种不同的切分方案。

输入描述:
\hspace{15pt}第一行输入两个整数 n \left( 3 \leqq n \leqq 2 \times 10^5 \right) 代表数组中的元素数量。
\hspace{15pt}第二行输入 n 个整数 a_1,a_2,\dots,a_n \left( -10^9 \leqq a_i \leqq 10^9 \right) 代表数组元素。


输出描述:
\hspace{15pt}在一行上输出一个整数,代表切分方案数。
示例1

输入

3
3 3 3

输出

1
示例2

输入

6
1 1 4 5 1 4

输出

0
示例3

输入

10
0 3 4 2 3 2 1 -1 3 4

输出

2
#include <stdio.h>

int main() {
    int n = 0;
    scanf("%d", &n);
    int a[200000] = {0};
    int sum = 0;
    int s[200000] = {0};//前缀和
    int d1[200000] = {0};//1/3位置
    int d2[200000] = {0};//2/3位置
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
        sum += a[i];
        s[i] = sum;
    }
    int result  = 0;
    if (sum != 0) {
        if (sum % 3 == 0) {
            int cnt1 = 0;
            int cnt2 = 0;

            for (int i = 0; i < n ; i++) {
                if (s[i] == sum / 3) {
                    int flag = 0;//前1/3有正数
                    for (int j = 0; j <= i; j++) {
                        if (a[j] > 0) {
                            flag = 1;
                            break;
                        }
                    }
                    if (flag) {
                        d1[cnt1++] = i;
                        flag = 0;
                    }

                }
            }
            for (int i = n - 1; i >= 0 ; i--) {
                if (s[i] == 2 * sum / 3) {
                    int flag = 0;//后1/3有正数
                    for (int j = n - 1; j >= i; j--) {
                        if (a[j] > 0) {
                            flag = 1;
                            break;
                        }
                    }
                    if (flag) {
                        d2[cnt2++] = i;
                        flag = 0;
                    }
                }
            }

            //结果
            for (int i = 0; i < cnt1; i++) {
                for (int j = 0; j < cnt2; j++) {
                    if (d2[j] > d1[i]) {
                        //中间1/3有正数
                        int flag = 0;
                        for (int k = d1[i]; k <= d2[j]; k++) {
                            if (a[k] > 0) {
                                flag = 1;
                                break;
                            }
                        }
                        if (flag) {
                            result++;
                            flag = 0;
                        }
                    }
                }
            }
        }
    } 
    // else if (sum == 0) {
    //     int cnt = 0;
    //     for (int i = 0; i < n ; i++) {
    //         if (s[i] == 0) cnt++;
    //     }
    //     cnt--;
    //     result = cnt * (cnt - 1) / 2;
    // }
    printf("%d", result);
    return 0;
}



发表于 2025-09-28 21:37:15 回复(0)