【问题标题】:Troubleshooting a nested FOR loop that increments two variables对递增两个变量的嵌套 FOR 循环进行故障排除
【发布时间】:2020-12-10 09:28:29
【问题描述】:

我正在尝试解决 CSES 上的公寓问题。对编码非常陌生,而不是在寻找解决方案.. 只是帮助解决问题。

https://cses.fi/problemset/task/1084/.

我想根据成本将 n 个申请人匹配到 m 个公寓,并给出每个人的列表。它适用于样本输入,但许多测试仍然失败。我认为问题在于我在嵌套 for 循环中的向量操作。

失败的测试示例

n 10 
m 10 
k 10 
n integers  90 41 20 39 49 21 35 31 74 86  
m integers  14 24 24 7 82 85 82 4 60 95 

aptsMatched 的预期结果:6,我的结果:3

#include <bits/stdc++.h>
using namespace std;

int main() {

    int n, m, k, aptfill, aptsize;
    int aptsMatched = 0;
    vector<int> desiredSize;
    vector<int> apts;
    int b=0;
    cin >> n;
    cin >> m;
    cin >> k;

我确信有更好的方法可以做到这一点。但我是全新的,并试图以直观的方式做到这一点。能够使用以下输入成功填充我的向量。

    for (int i = 0; i < n; i++) {
        cin >> aptfill;
        desiredSize.push_back(aptfill);
        sort(desiredSize.begin(), desiredSize.end());
        reverse(desiredSize.begin(), desiredSize.end());

    }

    for (int i = 0; i < m; i++) {
        cin >> aptsize;
        apts.push_back(aptsize);
        sort(apts.begin(), apts.end());
        reverse(apts.begin(), apts.end());

    }

我正在尝试迭代 apts 向量 3x,每次在迭代 desiredSize 向量索引时保持 apts 索引值不变。怀疑嵌套循环有问题 - j

    for (int i = 0; i < m; i++) {  

        for (int j = 0; j < desiredSize.size(); j++) {
            
            if (abs(apts[b] - desiredSize[j]) <= k) {                  
                desiredSize.erase(desiredSize.begin() + j);
                b++;
                aptsMatched++;
                break;
            }
            else {
                continue;


            }
        }
    }

    cout << aptsMatched;
}

我意识到这段代码非常可怕,并且有更快的方法来实现相同的想法。我首先想了解这种方法(如果一开始没有完全缺陷的话),但我也愿意接受更有效的方法来解决这个问题。

谢谢

【问题讨论】:

  • 一个明显的改进是在输入值后对向量进行排序。无需重复对向量进行排序。
  • else { continue; } 是不必要的和分散注意力的。循环会自动继续,您无需请求它们继续。
  • 但主要的问题是你没有说出真正的问题。你会撞车吗?出乎意料的结果?为了获得帮助,您确实应该首先说出问题所在。
  • 我无法编译这个。请阅读Why should I not #include &lt;bits/stdc++.h&gt;?
  • 代码运行,但它不会产生所有测试的预期结果。稍后,我将提供我正在尝试的输入以及我的期望

标签: c++ algorithm for-loop vector nested


【解决方案1】:

一种方法是对所需尺寸和公寓尺寸进行排序,然后从最小和向上开始匹配。

例子:

#include <algorithm>
#include <iostream>
#include <vector>

int main() {
    int max_diff = 10;

    std::vector<int> desired{90, 41, 20, 39, 49, 21, 35, 31, 74, 86};
    std::vector<int> apts{14, 24, 24, 7, 82, 85, 82, 4, 60, 95};

    std::sort(desired.begin(), desired.end());
    std::sort(apts.begin(), apts.end());

    int aptsMatched = 0;

    auto dit = desired.begin(); // iterator to the desired sizes
    auto ait = apts.begin();    // iterator to appartment sizes
        
    // loop until one of them reaches the end
    while(dit != desired.end() && ait != apts.end()) {
        // do we have a good fit?

        if(*dit + max_diff >= *ait   // the maximum size is >= appartment size
           &&
           *dit - max_diff <= *ait ) // the minimum size is <= appartment size
        {
            ++aptsMatched;
            ++dit;
            ++ait;
        } else // not a good fit, step the iterator to the smallest size
            if(*dit < *ait) ++dit;
            else ++ait;
    }

    std::cout << aptsMatched << '\n';
}

【讨论】:

    【解决方案2】:

    我想根据成本将 n 个申请人匹配到 m 个公寓

    但是没有成本;你的意思是想要的尺寸,对吧? ...但即便如此 - 如何您希望将申请人与公寓相匹配?

    由于您是初学者,请考虑用您自己的话用英语写下您的算法 - 既适合您自己,也适合您在编写 C++ 代码之前,也适合我们(如果您需要帮助了解问题所在)。

    另外,这里有一些危险信号:

    • 您正在重复对(部分)数据进行排序 - 分别为 nm 次!这几乎肯定是错误的做法。
    • 您正在反复反转您的(部分)数据。这似乎也很多余。

    您的代码的其他问题:

    • 您真的应该包含标准未定义的内部库标头,例如&lt;bits/whatever&gt;。见here
    • 您的速记名称令人困惑。首先,nm 非常不透明。还有,aptfillb?不知道这是什么意思。
    • 为什么要在一个方向上排序,然后反过来呢?只需按相反的方向排序。或者,您也可以向后迭代已排序的数组。

    【讨论】:

      猜你喜欢
      • 2017-01-20
      • 1970-01-01
      • 2018-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多