本题类似于有几个PAT,区别是,之前的题是记录A的左边有几个P,右边有几个T,而本题是记录左边的最大值,右边的最小值。
输入:
5
1 3 2 4 5
输出:
3
1 4 5
参考柳神的另一种解法,对数组用快排,如果位置不变,大概率就是主元,但是还需要判断是不是左边都小于这个数(判断右边都大于这个数也可以)。
#include<stdio.h>
#include<algorithm>
using namespace std;
int main(){
int n;
scanf("%d", &n);
int num[n]={0};
int rnum[n]={0};
int ln[n] = {0}; //记录左边的最大值
ln[0] = 0;
int p[n] = {0};
int count = 0;
for(int i=0;i<n;i++){
scanf("%d", num+i);
rnum[i] = num[i];
if(i>=1&&num[i]>ln[i-1]){
ln[i] = num[i-1];
}else{
ln[i] = ln[i-1];
}
}
sort(num,num+n-1);
for(int i=0;i<n;i++){
if(num[i]==rnum[i]&&num[i]>ln[i]) p[count++] = num[i];
}
printf("%d\n", count);
if(count==0){
printf("\n");
return 0;
}
for(int i=0;i<count;i++){
printf("%d", p[i]);
if(i<count-1) printf(" ");
}
return 0;
}
测试点2比较坑,要求在没有主元的情况下,输出0\n\n,才能通过,醉了。
代码如下:
#include<stdio.h>
using namespace std;
const int maxn = (1<<30)-1;
int main(){
int n;
scanf("%d", &n);
int num[n]={0};
for(int i=0;i<n;i++){
scanf("%d", num+i);
}
int p[n] = {0}; //记录满足题意的数
int count = 0; //满足题意的数的个数
int ln[n] = {0}; //记录左边的最大值
int rn[n] = {0}; //记录右边的最小值
ln[0] = 0;
rn[n-1] = maxn;
for(int i=1;i<n;i++){
if(num[i]>ln[i-1]){
ln[i] = num[i-1];
}else{
ln[i] = ln[i-1];
}
}
for(int i=n-2;i>=0;i--){
if(num[i]<rn[i+1]){
rn[i] = num[i+1];
}else{
rn[i] = rn[i+1];
}
}
for(int i=0;i<n;i++){
if(num[i]>ln[i]&&num[i]<rn[i]) p[count++] = num[i];
}
printf("%d\n", count);
if(count==0){
printf("\n");
return 0;
}
for(int i=0;i<count;i++){
printf("%d", p[i]);
if(i<count-1) printf(" ");
}
return 0;
}
自己写的随机快排:
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<math.h>
using namespace std;
int quickSort(int num[], int left, int right){
int p = round(1.0*rand()/RAND_MAX*(right-left)+left);
int t = num[p];
num[p] = num[left];
num[left] = t;
int temp = num[left];
while(left<right){
while(left<right&&num[right]>temp) right--;
num[left] = num[right];
while(left<right&&num[left]<temp) left++;
num[right] = num[left];
}
num[left] = temp;
return left;
}
void solve(int num[], int left, int right){
if(left<right){
int pos = quickSort(num, left, right);
solve(num, left, pos-1);
solve(num, pos+1, right);
}
}
int main(){
srand((unsigned) time(NULL));
int n;
scanf("%d", &n);
int num[n]={0};
int rnum[n]={0};
int ln[n] = {0}; //记录左边的最大值
ln[0] = 0;
int p[n] = {0};
int count = 0;
for(int i=0;i<n;i++){
scanf("%d", num+i);
rnum[i] = num[i];
if(i>=1&&num[i]>ln[i-1]){
ln[i] = num[i-1];
}else{
ln[i] = ln[i-1];
}
}
solve(num,0,n-1);
for(int i=0;i<n;i++){
if(num[i]==rnum[i]&&num[i]>ln[i]) p[count++] = num[i];
}
printf("%d\n", count);
if(count==0){
printf("\n");
return 0;
}
for(int i=0;i<count;i++){
printf("%d", p[i]);
if(i<count-1) printf(" ");
}
return 0;
}
测试点2应该的输出: