1 条题解
-
0
思路
考虑一般的找最值方法是什么,这里以最大值为例。
显然就是擂台法,即先钦定第一个值为最大值,然后依次向后比较,出现比它大的就替换,最终得到的值就是最值。
假如有 个数,那么需要比较 次,但是这题需要同时找出最小值和最大值,一般做法就是找两次,询问次数为 ,不能通过,考虑优化。
假如对于两个数 有 ,那么 不可能为最小值, 不可能为最大值,证明显然。
于是先对所有数两两询问,便可以将所有数分成两组,第一组中为不可能是最大值的数,第二组为不可能是最小值的数,于是最小值一定在第一组,最大值一定在第二组,再使用一般的找最值方法即可。询问次数为 ,可以通过。
代码 1
注意 时的特殊情况。
#include <bits/stdc++.h> using namespace std; int Compare(int X,int Y); void Answer(int X,int Y); vector<int> b,s; void Ramen(int N){ if(N==1){ Answer(0,0); return; } for(int x,i=0;i<N-1;i+=2){ x=Compare(i,i+1); if(x==1) b.push_back(i),s.push_back(i+1); else b.push_back(i+1),s.push_back(i); } if(N%2){ int x=Compare(N-2,N-1); if(x==1) s.push_back(N-1); else b.push_back(N-1); } int B=b[0],S=s[0]; for(int x,i=1;i<b.size();i++){ x=Compare(B,b[i]); if(x==-1) B=b[i]; } for(int x,i=1;i<s.size();i++){ x=Compare(S,s[i]); if(x==1) S=s[i]; } Answer(S,B); }
如果你不想写这么多代码怎么办呢?有的兄弟,有的。在 c++ 中有一个函数
minmax_element,作用是在 次比较内找出序列最小值与最大值,该函数实现方法跟以上思路完全一致,于是我们便只用三行写完了本题代码。代码 2
#include <bits/stdc++.h> using namespace std; int Compare(int X,int Y); void Answer(int X,int Y); int a[405]; void Ramen(int N){ for(int i=0;i<N;i++) a[i]=i; auto [mn,mx]=minmax_element(a,a+N,[](int x,int y){return Compare(x,y)==-1;}); Answer(*mn,*mx); }
- 1
信息
- ID
- 4675
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 3
- 已通过
- 2
- 上传者