【解決方法】 C++: この問題を解決するにはどうすればよいですか? ほぼ理解できましたが、少し行き詰まっただけです


この問題に出会うまで C++ の問題を徹底的に解いていましたが、長い時間が経っても AC できなくなりました (サンプルに合格することさえできませんでした)。 助けてください!

農夫のジョンには、牛のためにどの種類の干し草を購入するかを考えるという重要な仕事があります。
農場主ジョンの牛 (2≤N≤10^5) には 1 から Nan までの番号が付けられ、各牛はちょうど 1 種類の干し草 h(i) を好みます: (1≤h(i)≤N。彼はすべての牛に同じ種類を好むよう望んでいます。干し草の。
これを実現するために、ファーマー ジョンはフォーカス グループを主催できます。 フォーカスグループは、ito j の番号が付けられた連続範囲内のすべての牛を集めて会議を行うことで構成されます。 グループ内の半数以上の牛が好む種類の干し草がある場合、フォーカス グループの会議が終了した後、すべての牛がその種類の干し草を好むことになります。 そのような種類の干し草が存在しない場合、牛は好みの干し草の種類を変更しません。 たとえば、16 頭の範囲の牛で構成されるフォーカス グループの場合、残りの牛が一致するように好みを切り替えるには、そのうちの 9 頭以上が同じ牧草の好みを持っている必要があります。
農場のジョンは、どの種類の干し草がすべての牛に同時に好まれるかを知りたいと考えています。 彼は一度に 1 つのフォーカス グループしかホストできませんが、すべての牛に同じ種類の干し草を好ませるために、必要な数のフォーカス グループを実行できます。

入力フォーマット:
1 つ目は、独立したテスト ケースの数を示す整数 T で構成されます (1≤T≤10)

各テスト ケースの最初の行は N で構成されます。
2 行目は N 個の整数で構成され、牛が好む干し草 h(i) の種類を順番に示します。
すべてのテスト ケースにわたる N の合計が 2⋅10^5 を超えないことが保証されます。

出力フォーマット:
T 行を出力します (テスト ケースごとに 1 行)。
すべての牛に同じ種類の干し草を同時に好ませることが可能であれば、可能なすべての種類の干し草を昇順に出力します。 それ以外の場合は、-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 は、すべての牛で単一のフォーカス グループを実行することによってこれを実行できます。
2 番目のテスト ケースでは、どの牛も好みの干し草の種類を変更しないことを示すことができます。
3 番目のテスト ケースでは、3 つのフォーカス グループを実行することで、すべての牛をタイプ 1 のようにすることができます。まず、フォーカス グループに牛 1 ~ 4 を入れ、次にフォーカス グループに牛 1 ~ 5 を入れ、次に牛を入れます。フォーカス グループの 1 ~ 6。 同様のロジックにより、牛 3 ~ 6、牛 2 ~ 6、次に牛 1 ~ 6 を使用すると、すべての牛をタイプ 2 のようにすることができます。
4 番目のテスト ケースでは、すべての牛に対して単一のフォーカス グループを実行することで、すべての牛をタイプ 3 のようにすることができます。
5 番目のテスト ケースでは、どの牛も好みの干し草の種類を変更しないことを示すことができます。

得点:

* 入力 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

コンパイルしたからといって、コードが正しいというわけではありません。 :笑う:
開発プロセスを電子メールを書くことと考えてください。コンパイルが成功したということは、電子メールを適切な言語 (たとえばドイツ語ではなく英語) で書いたことを意味します。電子メールに送信したいメッセージが含まれていたわけではありません。

これで、開発の第 2 段階 (実際には第 4 段階か第 5 段階ですが、後で初期段階に戻ります) に入ります: テストとデバッグ。

まず、それが何をするのか、そしてそれがあなたが望んでいることとどう違うのかを見てみましょう。 これは、なぜそのような動作をしているのかについての情報を提供するため、重要です。 たとえば、プログラムがユーザーに数値を入力させ、その数値を 2 倍にして答えを出力することを目的としている場合、入力/出力が次のようになったとします。

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

次に、問題はそれを 2 倍にするビットにあることは明らかです。ビット自体に加算したり 2 を乗算したりするのではなく、自身を乗算して入力の 2 乗を返します。
それで、コードを見ると、それがここのどこかにあることが明らかです。

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

何が問題なのかがわかったら、デバッガーを使用してその理由を調べてください。 メソッドの最初の行にブレークポイントを配置し、アプリを実行します。 ブレークポイントに到達すると、デバッガーは停止し、制御がユーザーに渡されます。 コードを 1 行ずつ実行し (「シングル ステップ」と呼ばれます)、必要に応じて変数の内容を確認 (または変更) できるようになりました (必要に応じて、コードを変更して再試行することもできます)。
コードを実行する前にコードの各行が何をすべきかを考え、それを「ステップオーバー」ボタンを使用して各行を順番に実行したときの実際の動作と比較してください。 期待通りの結果になりましたか? その場合は、次の行に進みます。
そうでない場合は、なぜそうではないのでしょうか? どう違うのでしょうか?
コードのどの部分に問題があるのか​​、また何が問題なのかを特定するのに役立つことを願っています。
これはスキルであり、開発だけでなく現実世界でも役立つため、伸ばす価値のあるスキルです。 すべてのスキルと同様、それは使用することでのみ向上します。

コメント

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