鱼C论坛

 找回密码
 立即注册
查看: 1519|回复: 2

为什么不对

[复制链接]
发表于 2023-10-31 17:11:50 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
描述
给定一个正整数序列,判断其中有多少个数,等于数列中其他两个数的和。 比如,对于数列1 2 3 4, 这个问题的答案就是2, 因为3 = 2 + 1, 4 = 1 + 3。

输入
共两行,第一行是数列中数的个数n ( 1 <= n <= 100),第二行是由n个不大于10000的正整数组成的数列,相邻两个整数之间用单个空格隔开。
输出
一个整数,即数列中等于其他两个数之和的数的个数。#include <iostream>
#include <vector>
using namespace std;
int main()
{
        int n;
        int count = 0;
        cin >> n;
        if (n == 1 or n == 2)
        {
                cout << 0;
                return 0;
        }
        vector<int> nums;
        int num;
        for (int i = 1; i <= n; i++)
        {
                cin >> num;
                nums.push_back(num);
        }
        for (int i = 0; i < nums.size(); i++)
        {
                for (int j = i+1; j < nums.size(); j++)
                {
                        for (int k = 0; k < nums.size(); k++)
                        {
                                if ((nums[i] + nums[j] == nums[k] )&& (j!=k) && (k!=i))
                                {
                                        count = count + 1;
                                }
                        }
                }
        }
        cout << count;
        return 0;
}为什么错了
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-10-31 17:12:25 | 显示全部楼层
问题出在第三个循环中,你遍历了整个数列来判断是否存在一个数等于其他两个数的和。然而,这样的做法会导致重复计数。例如,在数列1 2 3 4中,当i=0, j=1时,你会发现3=1+2,然后当i=1, j=0时,你又会发现3=2+1,这样就重复计数了。因此,你需要修改第三个循环的范围,只需遍历从i+1到n-1的数即可。
以下是修改后的代码:
  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;
  4. int main()
  5. {
  6.     int n;
  7.     int count = 0;
  8.     cin >> n;
  9.     if (n == 1 or n == 2)
  10.     {
  11.         cout << 0;
  12.         return 0;
  13.     }
  14.     vector<int> nums;
  15.     int num;
  16.     for (int i = 1; i <= n; i++)
  17.     {
  18.         cin >> num;
  19.         nums.push_back(num);
  20.     }
  21.     for (int i = 0; i < nums.size(); i++)
  22.     {
  23.         for (int j = i+1; j < nums.size(); j++)
  24.         {
  25.             for (int k = i+2; k < nums.size(); k++)
  26.             {
  27.                 if ((nums[ i] + nums[j] == nums[k] )&& (j!=k) && (k!=i))
  28.                 {
  29.                     count = count + 1;
  30.                 }
  31.             }
  32.         }
  33.     }
  34.     cout << count;
  35.     return 0;
  36. }
复制代码

这样修改后,你的代码应该能够正确计算等于其他两个数之和的数的个数了。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 0 反对 1

使用道具 举报

发表于 2023-10-31 17:13:18 | 显示全部楼层
问题出在第三层循环中,每次都需要判断k是否等于ij,这样会导致重复计算。另外,在第二层循环中,j应该从i+1开始,因为不需要重复计算已经被计算过的组合。

正确的代码如下:
  1. ++
  2. #include <iostream>
  3. #include <vector>
  4. using namespace std;
  5. int main()
  6. {
  7.     int n;
  8.     int count = 0;
  9.     cin >> n;
  10.     if (n == 1 or n == 2)
  11.     {
  12.         cout << 0;
  13.         return 0;
  14.     }
  15.     vector<int> nums;
  16.     int num;
  17.     for (int i = 1; i <= n; i++)
  18.     {
  19.         cin >> num;
  20.         nums.push_back(num);
  21.     }
  22.     for (int i = 0; i < nums.size(); i++)
  23.     {
  24.         for (int j = i + 1; j < nums.size(); j++)
  25.         {
  26.             for (int k = j + 1; k < nums.size(); k++) // 注意是从j+1开始
  27.             {
  28.                 if (nums[i] + nums[j] == nums[k])
  29.                 {
  30.                     count++;
  31.                 }
  32.             }
  33.         }
  34.     }
  35.     cout << count;
  36.     return 0;
  37. }
复制代码

此外,可以针对题目条件进行优化。如果将数列按升序排序,那么对于每个数num,只需要在比它大的数中查找是否有两个数的和等于它即可,这样可以避免重复计算。

优化后的代码如下:
  1. ++
  2. #include <iostream>
  3. #include <vector>
  4. #include <algorithm>
  5. using namespace std;
  6. int main()
  7. {
  8.     int n;
  9.     int count = 0;
  10.     cin >> n;
  11.     if (n == 1 or n == 2)
  12.     {
  13.         cout << 0;
  14.         return 0;
  15.     }
  16.     vector<int> nums;
  17.     int num;
  18.     for (int i = 1; i <= n; i++)
  19.     {
  20.         cin >> num;
  21.         nums.push_back(num);
  22.     }
  23.     sort(nums.begin(), nums.end()); // 排序
  24.     for (int i = nums.size() - 1; i >= 0; i--)
  25.     {
  26.         int left = 0, right = i-1; // 双指针初始化
  27.         while (left < right)
  28.         {
  29.             if (nums[left] + nums[right] == nums[i])
  30.             {
  31.                 count++;
  32.                 break;
  33.             }
  34.             else if (nums[left] + nums[right] < nums[i])
  35.             {
  36.                 left++;
  37.             }
  38.             else
  39.             {
  40.                 right--;
  41.             }
  42.         }
  43.     }
  44.     cout << count;
  45.     return 0;
  46. }
复制代码

希望这些修改能够帮助您解决问题。

球一个最佳答案谢谢啦!这对我非常重要!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-22 00:57

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表