T1 数字配对 题解
T1 数字配对 题解
题目描述
对于给定的一列数字,数字个数为偶数,你需要解决如下问题:
将给定的数列中的数字两两配对,这样每一对数字的和将形成一个新数列,对于不同的配对方法,新数列中的最大值也不同,寻找一个好的配对方法,使得新数列中的最大值最小。
输入格式
第一行一个整数 n(n<=10000)。 第二行有 n 个正整数,为给定的一列数字(数字均小于 maxint div 2)。
输出格式
一个正整数,新数列中的最大值的最小值。
输入输出样例
输入
4
1 5 2 8
输出
9
说明/提示
1 与 8 配对
2 与 5 配对
新的配对数列:9 7
(最大的)结果为 9。
当然,这里也可以1与5配对,2与8配对,结果:6,10 (最大的)结果为10,要比上一个9大
------------
题目分析
这道题虽然很氵,但是我们也不能太轻视这道题,也有许多需要注意的点
比如freopen,排序等等
如果这道题你的思路对了,那么这道题可能只需要五分钟就能做完,
因为个数是偶数个,所以,每个数字一定会有配对的数字。 为了让最大值最小,只需要有把最大的数字和最小的数字配对就可以,怎么理解呢?
就拿样例来说
1 5 2 8从大到小排序后为:
1 2 5 8
如果小的跟小的配对,也就是1跟2配对。那么这一组是肯定小的(1+2=3),但这肯定不是最大值,剩下的两个大的也得配对,这样就会比原方法更大(5+8=13),题目要求是让新数列中的最大值最小,很明显这种配对方法中最大值13要比原方法中的最大值9要大
因此 你可以这样做:
- 所有的数字从小到大排序,
- 然后 第一个(最小)和 最后一个(最大)配对,第二个(第二小)和 倒数第二个(倒数第二小)配对,以此类推,直到完成配对。
这里是偶数个所以不需要考虑有剩余的问题
配对之后新数列的最大值就是所有可能的配对的最大值的最小可能。
其实仔细观察提示和样例就可以很轻松的理清思路了
这就很像我们小学学过的搭桥问题,10可以拆成1和9,2和8,3和7,他们和都是10,只不过这道题中和各不相同
1.输入
int n; cin>>n; int s[10000]; for(int i=0;i<n;i++){ cin>>s[i]; }
*注意数组不要开小了,也不要开大了,主函数里放不开
2.排序
使用快速排序sort最方便,但要注意加上头文件algorithm
#include <algorithm>
sort的用法:
sort ( 数组名 ,数组名+排序长度(表达式),升序/降序(选填,默认升序) )
sort(begin,end,cmp)
sort(s,s+n);
当然你也可以使用冒泡排序等等,但是耗时要比快速排序慢
3.找最大的配对
这里就要牵扯到找最大值,可以用max打擂台,也可以存起来排序一遍
i是前半部分,n-i-1就是后半部分,因此一直循环到n/2即可
for(int i=0;i<n/2;i++){ if(max<s[i]+s[n-i-1]){ max=s[i]+s[n-i-1]; } }
cout<<max;
排序法
for(int i=0;i<n/2;i++){ s1[i]=s[i]+s[n-i-1]; } sort(s1,s1+n);//这里也可以改成从大到小排序,下面改成s1[0] cout<<s1[n-1];
完整代码:
#include <iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<cstring> using namespace std; int main(){ // freopen("number.in","r",stdin); // freopen("number.out","w",stdout); int n; cin>>n; int s[10000],s1[10000],max=-1; for(int i=0;i<n;i++){ cin>>s[i]; } sort(s,s+n); for(int i=0;i<n/2;i++){ s1[i]=s[i]+s[n-i-1]; } sort(s1,s1+n); cout<<s1[n-1]; fclose(stdin); fclose(stdout); return 0; }
谢谢大家
自古水题出人才