pat A1101
题意:

输入输出:

解题思路:

参考代码:
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN=100010;
const int INF=0x3fffffff; //一个很大的数
int a[MAXN],leftMax[MAXN],rightMin[MAXN];
int ans[MAXN],num=0;
/*
原理:
1.找出每一位左边最大数,右边最小数
2.题目中的意思是,给出的这些数,哪些是左边的数都比他小,右边的数都比他大则满足
3.所以左边最大的数都比它小,那么左边所有的数都比他小,如果右边最小的数比它大,则右边所有的数都比他大
4.注意在leftMax中,第一个数设为0,在rightMin中,最后一个数设置为最大的inf,这样设置可以保证在数组头
就被算进,在数组尾,也同样能被算进;所以同样的在遍历循环时,leftMax数组是从1开始到结束,rightMin数组是
从倒数第2位(也就是n-2)开始,一直到数组头
5.如果遍历原始数组,并且与leftMax和Rightmin数组进行对比,然后能对上则保存原始的数组元素,并统计个数
*/
int main()
{
int n;
cin >> n; //序列元素个数
for(int i=0; i<n; i++)
cin >> a[i]; //输入序列元素
leftMax[0]=0; //每一位左边最大数,不包含本位,不包含第一个
for(int i=1; i<n; i++)
leftMax[i]=max(leftMax[i-1],a[i-1]); //由i-1推得i
rightMin[n-1]=INF; //每一位右边最小数,不包含本位,不包含最后一个,注意末尾设置一个很大的数字
for(int i=n-2; i>=0; i--)
{
rightMin[i]=min(rightMin[i+1],a[i+1]); //由i+1推得i
}
for(int i=0; i<n; i++)
{
if(leftMax[i]<a[i] && rightMin[i]>a[i])
ans[num++]=a[i]; //记录主元
}
printf("%d\n",num); //输出主元个数
for(int i=0; i<num; i++)
{
printf("%d",ans[i]); //依次输出所有主元
if(i<num-1)
cout << " ";
}
cout << endl;
return 0;
}
知识总结:
1.通过用16位进制数来设置一个很大的数
#include<iostream>
using namespace std;
const int maxn=100001;
int leftMax[maxn],rightMin[maxn],ans[maxn],news[maxn];
int main()
{
cout << 0x3fffffff << endl; //用0x来引导的是表示16进制,下面f表示15
cout << 0x12; //表示16进制的12 ,也就是18
return 0;
}


被折叠的 条评论
为什么被折叠?



