PAT甲级 1045快速排序

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

int main()
{
   int N;
   cin>>N;
   int a[N],b[N]={0};
   for(int i=0;i<N;i++){
       cin>>a[i];
   }
   int isprime=1,count=0;
   for(int i=0;i<N;i++){
       int isprime=1;
       for(int j=0;j<i;j++){
           if(a[j]>a[i]){
               isprime=0;
           }
       }
       for(int j=i+1;j<N;j++){
           if(a[j]<a[i]){
               isprime=0;
           }
       }
       if(isprime==1){
           count++;
           b[i]=a[i];
       }
   }
   cout<<count<<endl;
   sort(b,b+N);
   int first=0;
   for(int i=0;i<N;i++){
       if(b[i]!=0 && first==0){
           cout<<b[i];
           first=1;
       }else if(b[i]!=0 && first==1){
           cout<<" "<<b[i];
       }
   }
   return 0;
}

元のコードは二重ループを使用しており、時間制限超過が発生するため、以下のように最適化しました:

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

int main() {
    int N;
    cin >> N;

    vector<int> data(N);
    vector<int> maxLeft(N);
    vector<int> minRight(N);

    for (int i = 0; i < N; i++) {
        cin >> data[i];
    }

    maxLeft[0] = 0;
    for (int i = 1; i < N; i++) {
        maxLeft[i] = max(maxLeft[i - 1], data[i - 1]);
    }

    minRight[N - 1] = 1e9 + 1;
    for (int i = N - 2; i >= 0; i--) {
        minRight[i] = min(minRight[i + 1], data[i + 1]);
    }

    int total = 0;
    vector<int> output;
    for (int i = 0; i < N; i++) {
        if (data[i] > maxLeft[i] && data[i] < minRight[i]) {
            total++;
            output.push_back(data[i]);
        }
    }

    cout << total << endl;
    sort(output.begin(), output.end());
    for (int i = 0; i < total; i++) {
        cout << output[i];
        if (i != total - 1) {
            cout << " ";
        }
    }
    cout<<endl;

    return 0;
}

この改善版では、同じ戦略を採用しつつ、ループ回数を削減しています。具体的な改善点は以下の通りです:

  • 配列の代わりに vector を使用することで、固定サイズの配列定義を回避します。
  • maxLeft および minRight の計算において、配列を一度だけ走査します。
  • 各要素が基準値として成立するかを判断する際、二重ループではなく maxLeftminRight の配列を用います。

タグ: アルゴリズム パフォーマンス最適化 C++ PAT

5月17日 01:23 投稿