[伯俊]17298号:ああ、大数


ここをクリック題が見えます.

📕 問題の説明



📕 問題を解く


私の解決策は次のとおりです.
私が問題を解決するポイントは大数の定義です.
問題は
AIA iAiの最大値は右側であり、AIA iAiより大きい数の中で最も左側にある数である.
次のように定義します.
AIA iAiの隣接する要素Ai+1 A i+1}Ai+1がAIA iAiより大きい場合は、他の要素を見る必要がなく、Ai+1 A i+1}Ai+1がAIA iAiの最大値になります.
ただし、上記の場合とは異なり、すぐに最大数が見つからない場合があります.いいえ、もっと多くなります.

📗 例1


問題の例で説明します.

上記の例の5つの整数を探してみましょう.
上述したように、最大値を検索する第1の方法は、Ai+1 A{i+1}Ai+1がAiaiAiの最大値であることを確保することである.
では最初は3と5を比較しますね5は3より大きいので、3の5つの数です.もちろん、他の要素も見る必要はありません.5は3より大きいので、一番左にあります.

今は5と2を比較します.2は5の5大数ではないので、このステップでは5の5大数が見つからずスキップします.
次に2と7を比較します.7は2の5の大きい数2の5の大きい数の中で7を入れます

さっきここで呉大洙が見つからなかったことを考えてみましょう.2の5大数7は5の5大数であってもよい.そこで、5の5大数で7を追加します.

このような状況を広めましょう.
最大値を見つける第1の方法は、前述したように、AIA iAiをAi+1 A{i+1}Ai+1と比較することである.
つまり.
Ai逆に
Ai≧Ai+1 A i≧A{i+1}Ai≧Ai+1の場合、今すぐにAiA iAiの最大値が見つからない場合は、まずAiA iAiを保存してください.
この状態で、ある日、Aiこの場合、見つからない5つの要素を格納し、1つずつ取り出してみると、適切な資料構造はStackになります.
上記の例を完了して一般化した場合、他の例を挙げます.
7が最後の要素であるため、整数にできる要素は存在しないため、問題の定義に従って、-1を出力アレイに追加します.

次に、トラブルシューティングの一般化を整理し、次の例に進みます.

📗 問題解決の一般化

  • 奥の大数を見つける基本的な方法はAiA iAiとAi+1 A{i+1}Ai+1を比較することである.
  • Ai
  • Ai≧Ai+1 Ai≧A{i+1}Ai≧Ai+1では最大数が見つからないため、AiAiをスタックに格納する.
  • Ai
  • stack.top()
  • の最後の要素と比較して、最大数が見つからなかった要素の最大数は-1です.
  • 📗 例2



    上記の例を示すと、トラブルシューティングを適用して各要素の最大数を検索します.
  • 奥の大数を見つける基本的な方法はAiA iAiとAi+1 A{i+1}Ai+1を比較することである.
  • 解析の適用
    初めては9と5を比較しました.
    9は5未満です.
  • Ai≧Ai+1 Ai≧A{i+1}Ai≧Ai+1では最大数が見つからないため、AiAiをスタックに格納する.
  • 9をスタックに保存します.
    でもここで考えてみようあとでAiしたがって、9と9のindexを同時にスタックに格納する必要があります.

    今は5と4を比較します.4は5より小さいので、5より大きい数字が見つからないので、スタックに入れてください.

    次に4と8を比較します.
  • Ai8は4の整数なので、出力アレイに追加できます.
  • Aiスタックに要素があるので、8がその要素の整数であるかどうかを1つずつ取り出して比較します.
    5<85<85<8.
  • stack.top()によると、8は5の5大数です.そして5の5つの数を見つけて、5をスタックから取り出します.

    9は8より大きいので、8は9の整数ではありません.その後、Ai8は最後の要素であるため、大きな整数は存在しないので、大きな整数-1を処理することができる.
  • の最後の要素と比較して、最大数が見つからなかった要素の最大数は-1です.
  • 最後の要素を比較したが、9の最大値が見つからなかったため、処理-1.

    📕 Code


    コードで表しましょう.
    #include <iostream>
    #include <stack>
    #include <vector>
    #include <utility>
    
    using namespace std;
    
    vector<int> nums(1'000'001);
    vector<int> answer(1'000'001);
    
    int main(void)
    {
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);
        cout.tie(NULL);
    
        int n;  cin >> n;
        for(int i=0; i<n; i++)
            cin >> nums[i];
    
        stack<pair<int, int>> st;	// Ai와 idx를 저장할 스택
        for(int i=0; i<n-1; i++)
        {
            if(nums[i] < nums[i+1])	// A[i] < A[i+1] 이면 오큰수를 찾음
            {
                answer[i] = nums[i+1];	// 오큰수 저장
                while(!st.empty() && st.top().first < nums[i+1])
                {		// 스택에 저장된 오큰수를 찾지 못한 원소들을 하나씩 꺼내어 
                		// A[i+1] 이 오큰수가 되는 지 비교
                    answer[st.top().second] = nums[i+1];	// 오큰수가 된다면 추가!
                    st.pop();	// 오큰수를 찾았으므로 pop!
                }
            }
            else
                st.push(make_pair(nums[i], i));	// A[i] >= A[i+1] 이면 
                					// 오큰 수를 찾지 못했으므로 
     		                                // 스택에 저장!
        }
        st.push(make_pair(nums[n-1], n-1));		// 마지막 원소는 오큰수가 없으므로 스택에 저장
    
        while(!st.empty())		// 마지막 원소까지 비교했음에도 불구하고 
        				// 오큰수를 찾지 못한 원소들은
        {
            answer[st.top().second] = -1;	// -1 처리
            st.pop();
        }
    
        for(int i=0; i<n; i++)
            cout << answer[i] << ' ';
    
        return 0;
    }

    ありがとうございます.

    📕 ポスト


    同様に、同じ資料構造を使用しても、その資料構造を多方面からどのように使用するかを見る必要がある...
    一つの方法に集中するのではなく、違う角度から解決策を考えましょう.