第一题:
题意:现在有一个数列,让你找出这个数列里面有没有主元素,有的话输出Yes并且输出这个元素,没有的话输出No.
注:主元素是指如果数列里面有一个数的总个数大于这个数列里面元素总个数的话,我们就称这个数位主元素
样例输入:
5
1 2 3 3 3
5
1 2 3 3 4
样例输出:
Yes 3
No
题意:现在有一个数列,让你找出这个数列里面有没有主元素,有的话输出Yes并且输出这个元素,没有的话输出No.
注:主元素是指如果数列里面有一个数的总个数大于这个数列里面元素总个数的话,我们就称这个数位主元素
样例输入:
5
1 2 3 3 3
5
1 2 3 3 4
样例输出:
Yes 3
No
解题思路:一个数列里面如果有主元素,那么这个元素肯定有个特点,那就是这个元素肯定占据着这个数列第N/2+1小这个位置。这样我们就把问题转化为了求解这个数列第N/2+1小的这个数。求解到这个数之后我们循环一遍统计一下这个元素出现了多少次,如果这个元素出现的次数大于N/2那么就说明这个元素是主元素,如果小于等于N/2那么就说明这个元素不是主元素。
#include<iostream>
using namespace std;
int N; //N代表数字的总个数
int R[100005]; //R用来存储N个数
int Partition(int R[],int low,int high)
{
int i=low,j=high,pivot=R[low];
while(i<j)
{
while(i<j&&pivot<=R[j])
j--;
if(i<j)
swap(R[i++],R[j]);
while(i<j&&R[i]<=pivot)
i++;
if(i<j)
swap(R[i],R[j--]);
}
return j;
}
//返回第几个位置的元素是第k小
int Kth_Number(int R[],int low,int high,int k)
{
int pivotpos;
while(low<high)
{
pivotpos=Partition(R,low,high);
if(pivotpos==k)
return pivotpos;
else if(pivotpos>k)
return Kth_Number(R,low,pivotpos-1,k);
else if(pivotpos<k)
return Kth_Number(R,pivotpos+1,high,k);
}
}
int main()
{
//freopen("1.txt","r",stdin);
while(scanf("%d",&N)!=EOF)
{
for(int i=1;i<=N;++i)
scanf("%d",&R[i]);
int pos=Kth_Number(R,1,N,N/2+1);
int sum=0;
for(int i=1;i<=N;++i)
if(R[i]==R[pos])
sum++;
if(sum>N/2)
printf("Yes %d\n",R[pos]);
else printf("No\n");
}
}