C++:如何解决这个问题? 差不多明白了,只是有点卡住


我一直在研究 C++ 问题,直到遇到这个问题,很长一段时间后我都无法解决这个问题(甚至无法通过示例)。 请帮忙!

农夫约翰有一项重要任务 – 弄清楚要为他的奶牛购买什么类型的干草。
Farmer John 的 N 头牛 (2≤N≤10^5) 编号为 1 到 N,每头牛只喜欢一种类型的干草 h(i):(1≤h(i)≤N。他希望他所有的牛都喜欢同一类型干草。
为了实现这一目标,Farmer John 可以主持焦点小组活动。 焦点小组包括将编号为 ito j(含)的连续范围内的所有奶牛聚集在一起召开会议。 如果有一种干草是小组中超过一半的奶牛喜欢的,那么焦点小组会议结束后,所有奶牛最终都会喜欢这种干草。 如果不存在这种类型的干草,那么奶牛就不会改变它们喜欢的干草类型。 例如,在由 16 头奶牛组成的焦点小组中,其中 9 头或更多的奶牛需要具有相同的干草偏好,才能使其余奶牛改变其偏好以匹配。
农夫约翰想知道哪些类型的干草可以同时受到所有奶牛的喜爱。 他一次只能主持一个焦点小组,但他可以根据需要组织多个焦点小组,以使所有奶牛都喜欢同一类型的干草。

输入格式:
第一个由整数 T 组成,表示独立测试用例的数量 (1≤T≤10)

每个测试用例的第一行由 N 组成。
第二行由 N 个整数组成,依次为奶牛最喜欢的干草类型 h(i)。
保证所有测试用例的 N 之和不超过 2⋅10^5。

输出格式:
输出 T 行,每个测试用例一行。
如果可以让所有奶牛同时喜欢同一种干草,则按升序输出所有可能的此类干草。 否则,输出-1。 在同一行上打印数字列表时,用空格分隔相邻的数字,并确保该行不以任何无关的空格结尾。

样本输入:
5
5
1 2 2 2 3
6
1 2 3 1 2 3
6
1 1 1 2 2 2
3
3 2 3
2
2 1
样本输出:
2
-1
1 2
3
-1
在示例输入中,有 5 个测试用例。
在第一个测试用例中,只能使所有奶牛都像类型 2 一样。FJ 可以通过对所有奶牛运行一个焦点小组来做到这一点。
在第二个测试用例中,我们可以证明没有奶牛会改变它们喜欢的干草类型。
在第三个测试用例中,可以通过运行三个焦点组来使所有奶牛都像类型 1 一样 – 首先将奶牛 1 到 4 纳入焦点组,然后将奶牛 1 到 5 纳入焦点组,最后将奶牛纳入焦点组1 到 6 属于焦点小组。 按照类似的逻辑,使用奶牛 3 到 6,奶牛 2 到 6,然后奶牛 1 到 6,我们可以使所有奶牛都像类型 2 一样。
在第四个测试用例中,可以通过对所有奶牛运行单个焦点小组来使所有奶牛都像类型 3 一样。
在第五个测试用例中,我们可以证明没有奶牛会改变它们喜欢的干草类型。

评分:

* 输入 2:N=2。
* 输入 3-4:N≤50。
* 输入 5-6:对于所有 1≤i≤N−1,h(i)≤h(i+1)。
* 输入 7-15:无附加约束。

我尝试过的:

我已经编写了以下代码(甚至使示例 i/o 的输出最后一行错误):

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

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int T;
    cin >> T;
    while(T--) {
        int N;
        cin >> N;
        vector<int> h(N);
        for(int i=0; i<N; i++) {
            cin >> h[i];
        }

        map<int, int> count;
        for(int i=0; i<N; i++) {
            count[h[i]]++;
        }

        vector<int> possible;
        for(auto &p : count) {
            if(p.second > N/2) {
                possible.push_back(p.first);
            }
        }

        if(possible.empty()) {
            // Check for types of hay liked by exactly half the cows
            for(auto &p : count) {
                if(p.second == N/2) {
                    possible.push_back(p.first);
                }
            }
        }

        if(possible.empty()) {
            cout << -1 << "\n";
        } else {
            sort(possible.begin(), possible.end());
            for(int i=0; i<possible.size(); i++) {
                cout << possible[i] << (i == possible.size()-1 ? "\n" : " ");
            }
        }
    }

    return 0;
}

如果有人有任何可以通过问题的解决方案或更改代码,请告诉我! 非常感谢大家!

解决方案1

编译通过并不意味着你的代码是正确的! :笑:
将开发过程视为编写电子邮件:成功编译意味着您使用正确的语言(例如英语,而不是德语)编写了电子邮件,而不是电子邮件包含您想要发送的消息。

现在您进入了开发的第二阶段(实际上是第四或第五阶段,但稍后您将进入早期阶段):测试和调试。

首先看看它做了什么,以及它与您想要的有何不同。 这很重要,因为它为您提供了有关这样做的原因的信息。 例如,如果一个程序打算让用户输入一个数字,然后将其加倍并打印答案,那么如果输入/输出如下所示:

Input   Expected output    Actual output
  1            2                 1
  2            4                 4
  3            6                 9
  4            8                16

那么很明显,问题在于将其加倍的位 – 它不是将自身与自身相加,或将其乘以 2,而是将其与自身相乘并返回输入的平方。
因此,您可以查看代码,很明显它位于此处:

C++
int Double(int value)
   {
   return value * value;
   }

一旦您知道可能出了什么问题,就开始使用调试器来找出原因。 在方法的第一行放置一个断点,然后运行您的应用程序。 当到达断点时,调试器将停止,并将控制权交给您。 现在,您可以逐行运行代码(称为“单步执行”),并根据需要查看(甚至更改)变量内容(哎呀,您甚至可以更改代码,然后根据需要重试)。
在执行代码之前,请考虑代码中的每一行应该执行的操作,并将其与使用“Step over”按钮依次执行每一行时实际执行的操作进行比较。 它达到了你的预期吗? 如果是这样,请转到下一行。
如果没有,为什么不呢? 有什么不同?
希望这可以帮助您找到代码的哪一部分有问题以及问题是什么。
这是一项技能,而且非常值得培养,因为它可以帮助您在现实世界中以及在开发中。 和所有技能一样,它只会通过使用而提高!

コメント

タイトルとURLをコピーしました