方法1
题目要求主元是要满足它左边所有的元素都比它自身小,右边所有元素都比它自身大。所以,对于存入的数组我们可以将其排序。
很显然,如果一个数是主元,那么它在排序前后的两个数组中的索引是相同的
其次,在循环遍历中判断时,它本身就是从第一个元素到它自身的最大元素。
我的代码如下:
#include<cstdio>
#include<algorithm>
using namespace std;
int main(){
int n,a[99999],b[99999],c[99999],max=0,d=0;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b,b+n);
for(int i=0;i<n;i++){
if(max<a[i]){
max=a[i];
}
if(a[i]==b[i]&&a[i]==max){
c[d++]=a[i];
}
}
printf("%d\n",d);
for(int i=0;i<d;i++){
if(i<d-1){
printf("%d ",c[i]);
}
else
printf("%d",c[i]);
}
printf("\n");
return 0;
}
遇到的问题:
1.编译时无输出,因为忘记给d赋初值。
2.一开始数组空间开的太小,提交错误。
3.最后一行要加 printf("\n"),是因为没有主元的情况第一行输出0,第二行要保留。
方法2
很简单,只要能实现两个数组分别是leftMax[i]和rightMin[i],用于存储每一个a[i]所对应的的左边的最大值和右边的最小值即可
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
scanf("%d",&n);
int a[n],leftMax[n]={0},rightMin[n]={0};
rightMin[n-1]=INT_MAX;//需要为其假设一个最大值,之后才有可比较的值
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
for(int i=1;i<n;i++){
leftMax[i]=max(leftMax[i-1],a[i-1]);
}
for(int i=n-2;i>=0;i--){
rightMin[i]=min(rightMin[i+1],a[i+1]);
}
vector<int>result;
for(int i=0;i<n;i++){
if(a[i]>leftMax[i]&&a[i]<rightMin[i]){
result.push_back(a[i]);
}
}
printf("%d\n",result.size());
if(result.size()==0)//如果没有这样的主元,输出一个空行
printf("\n");
else
for(int i=0;i<result.size();++i){
if(i>0)
printf(" ");
printf("%d",result[i]);
}
return 0;
}
虽然题目要求按递增顺序输出,但并不需要再按递增顺序进行一次排序。因为按照主元性质,左侧主元一定比右侧主元小,所以只要按照序列中的顺序输出主元,主元本身就是按照递增顺序排序好的。