5 条题解

  • 1
    @ 2025-12-21 18:36:31
    #include <bits/stdc++.h>
    using namespace std;
    int main(){
        int n;
        cin>>n;
        int a[n+1];
        int j;
        int c=0;
        int b=0;
        for(int i=1;i<=n;i++){
            cin>>j;
            a[i]=j;
            b+=j;
        }
        for(int i=1;i<=n;i++){
            if(2*c+a[i]==b){
                cout<<i;
                return 0;
            }
            c+=a[i];
        }
        cout<<"-1";
    }
    
    • @ 2025-12-23 16:15:58

      很巧妙的写法,只用一个变量c来滚动计算(来一个新数就算一个)而没有提前开presum数组,空间复杂度低(没有提前开数组)。

      改进点1:这里前缀和是累计值,可能会超过int,最好写long long c

      改进点2: 变量命名尽量用英语单词缩写,方便理解意思

  • 0
    @ 2025-12-20 19:59:51
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int presum[100005]={0};
    
    int main(){
        int n;
        cin >> n;
        
        // 构建前缀和数组
        for(int i=1;i<=n;i++){
            int a;
            cin>>a;
            presum[i]=presum[i-1]+a;
        }
        
        // 查找中心下标
        for(int i=1;i<=n;i++){
            // 左侧和:presum[i-1]
            // 右侧和:presum[n] - presum[i]
            if(presum[i-1] == presum[n] - presum[i]){
                cout << i;  // 1-based索引
                return 0;
            }
        }
        
        cout << -1;  // 没找到中心下标
        return 0;
    }
    
    • 0
      @ 2025-12-20 19:59:49
      #include <bits/stdc++.h>
      using namespace std;
      typedef long ll;
      int presum[100005]= {0};
      int main(){
          int n;
          cin>>n;
          for(int i=1;i<=n;i++){
              int a;
              cin>>a;
              presum[i]=presum[i-1]+a;
          }
          for(int i=1;i<=n;i++){
              if(presum[i-1]==presum[n]-presum[i]){
                  cout<<i<<endl;
                  return 0;
              }
          }
          cout<<"-1"<<endl;
          return 0;
      
      }
      
      • 0
        @ 2025-12-20 19:34:37

        原题解公式较复杂,给一个更简单的公式

        维护前缀和数组presum[]的原理:

        • 0
          @ 2025-12-12 23:45:27

          这是一个用于生成“寻找平衡点”题目测试数据的完整 C++ 代码。它包含了 10 个精心设计的测试点,覆盖了样例、边界情况(如 N=1N=1、全 0、全正/负)以及大数据量的压力测试。

          数据生成器代码 (generator.cpp)

          您可以将以下代码保存为 generator.cpp,编译并运行。它将在当前目录下生成 1.in/1.out10.in/10.out

          #include <iostream>
          #include <fstream>
          #include <vector>
          #include <string>
          #include <random>
          #include <ctime>
          #include <numeric>
          #include <algorithm>
          
          using namespace std;
          
          // ==========================================
          // 1. 标准解法函数 (用于生成 .out 文件)
          // ==========================================
          long long solve(int n, const vector<int>& nums) {
              long long totalSum = 0;
              for (int x : nums) {
                  totalSum += x;
              }
          
              long long leftSum = 0;
              // 题目要求下标从1开始,但vector是0-based,我们在返回时 +1
              for (int i = 0; i < n; ++i) {
                  // 核心公式:2 * leftSum + currentVal == totalSum
                  if (2 * leftSum + nums[i] == totalSum) {
                      return i + 1; // 返回 1-based index
                  }
                  leftSum += nums[i];
              }
              return -1;
          }
          
          // ==========================================
          // 2. 随机数辅助工具
          // ==========================================
          mt19937 rng(time(nullptr));
          
          // 生成 [min, max] 范围内的随机整数
          int random_int(int min, int max) {
              uniform_int_distribution<int> dist(min, max);
              return dist(rng);
          }
          
          // ==========================================
          // 3. 测试点生成逻辑
          // ==========================================
          void generate_test_case(int id) {
              int N;
              vector<int> nums;
              string desc;
          
              switch (id) {
                  case 1: // 样例数据
                      N = 6;
                      nums = {1, 7, 3, 6, 5, 6};
                      break;
                  case 2: // 极小数据 N=1 (边界)
                      N = 1;
                      nums = {100}; 
                      // 解释:左和0,右和0,平衡点为1
                      break;
                  case 3: // 小数据随机 (大概率无解)
                      N = 10;
                      for(int i=0; i<N; ++i) nums.push_back(random_int(-10, 10));
                      break;
                  case 4: // 构造解:平衡点在最左边 (Index 1)
                      // 要求右边总和为 0
                      N = 100;
                      nums.push_back(random_int(-100, 100)); // Index 1 随便填
                      for(int i=1; i<N; i+=2) {
                          if (i+1 < N) {
                              int val = random_int(1, 100);
                              nums.push_back(val);
                              nums.push_back(-val); // 成对抵消,保证和为0
                          } else {
                              nums.push_back(0); // 补齐
                          }
                      }
                      break;
                  case 5: // 构造解:平衡点在最右边 (Index N)
                      // 要求左边总和为 0
                      N = 100;
                      for(int i=0; i<N-1; i+=2) {
                          if (i+1 < N-1) {
                              int val = random_int(1, 100);
                              nums.push_back(val);
                              nums.push_back(-val);
                          } else {
                              nums.push_back(0);
                          }
                      }
                      nums.push_back(random_int(-100, 100)); // Index N 随便填
                      break;
                  case 6: // 全 0 (解应为 1)
                      N = 200;
                      for(int i=0; i<N; ++i) nums.push_back(0);
                      break;
                  case 7: // 全正数 (大概率无解或特定解)
                      N = 100;
                      for(int i=0; i<N; ++i) nums.push_back(random_int(1, 100));
                      break;
                  case 8: // 全负数
                      N = 100;
                      for(int i=0; i<N; ++i) nums.push_back(random_int(-100, -1));
                      break;
                  case 9: // 大数据随机 (N=10^5)
                      N = 100000;
                      for(int i=0; i<N; ++i) nums.push_back(random_int(-1000, 1000));
                      break;
                  case 10: // 大数据构造有解 (回文数组)
                      // 奇数长度的回文数组,中间一定是平衡点
                      N = 99999; 
                      nums.resize(N);
                      for(int i=0; i<N/2; ++i) {
                          int val = random_int(-1000, 1000);
                          nums[i] = val;
                          nums[N-1-i] = val; // 对称位置相等
                      }
                      nums[N/2] = random_int(-1000, 1000); // 中间位置随便填
                      break;
              }
          
              // 修正 vector 大小以防 switch 中的逻辑有偏差
              if ((int)nums.size() != N) {
                  N = nums.size();
              }
          
              // --- 写入 .in 文件 ---
              string in_filename = to_string(id) + ".in";
              ofstream fin(in_filename);
              fin << N << "\n";
              for (int i = 0; i < N; ++i) {
                  fin << nums[i] << (i == N - 1 ? "" : " ");
              }
              fin << "\n";
              fin.close();
          
              // --- 计算答案并写入 .out 文件 ---
              long long ans = solve(N, nums);
              string out_filename = to_string(id) + ".out";
              ofstream fout(out_filename);
              fout << ans << "\n";
              fout.close();
          
              cout << "Generated Test Case " << id << ": N=" << N << " Ans=" << ans << endl;
          }
          
          int main() {
              // 生成 1 到 10 号测试点
              for (int i = 1; i <= 10; ++i) {
                  generate_test_case(i);
              }
              cout << "All test cases generated successfully!" << endl;
              return 0;
          }
          

          测试点覆盖说明 (Coverage Analysis)

          1. Case 1 (Sample): 题目自带的样例 1 7 3 6 5 6,用于基础验证。
          2. Case 2 (Boundary N=1): 数组只有一个元素,这是极易被忽略的边界。根据定义,左和0,右和0,答案应为 1
          3. Case 3 (Small Random): 小规模随机数,测试程序基本逻辑。
          4. Case 4 (Leftmost): 构造数据使得平衡点在 Index 1。这需要右侧总和为 0(通过正负数抵消构造)。
          5. Case 5 (Rightmost): 构造数据使得平衡点在 Index N。这需要左侧总和为 0。
          6. Case 6 (All Zeros): 全是 0。根据题目“输出最靠左的”,答案应为 1
          7. Case 7 (All Positive): 全是正数。测试前缀和单调递增的情况。
          8. Case 8 (All Negative): 全是负数。测试负数累加逻辑。
          9. Case 9 (Large Random): N=105N=10^5,数值随机。主要测试 O(N)O(N) 算法的性能,以及对无解情况的处理。
          10. Case 10 (Large Constructed): N105N \approx 10^5,构造成回文数组。这保证了中间点左右两侧元素完全对称,和一定相等,从而强制保证大数据下有解,测试程序在有解情况下的正确性。

          使用方法

          1. 保存为 generator.cpp
          2. 编译:g++ generator.cpp -o generator -std=c++11
          3. 运行:./generator
          4. 检查目录下生成的 1.in ~ 10.out 文件。
          • 1

          信息

          ID
          19320
          时间
          1000ms
          内存
          32MiB
          难度
          10
          标签
          (无)
          递交数
          6
          已通过
          4
          上传者