#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の計算において、配列を一度だけ走査します。- 各要素が基準値として成立するかを判断する際、二重ループではなく
maxLeftとminRightの配列を用います。