题干:
浙江桐乡乌镇共有n个人,请找出该镇上的前m个大富翁.
Input输入包含多组测试用例.
每个用例首先包含2个整数n(0<n<=100000)和m(0<m<=10),其中: n为镇上的人数,m为需要找出的大富翁数, 接下来一行输入镇上n个人的财富值.
n和m同时为0时表示输入结束.Output请输出乌镇前m个大富翁的财产数,财产多的排前面,如果大富翁不足m个,则全部输出,每组输出占一行.Sample Input
3 1
2 5 -1
5 3
1 2 3 4 5
0 0
Sample Output
5
5 4 3
解题报告:水题,排序即可,优先队列亦可解。
排序ac:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;int a[100000+5];
int main()
{int n,m;while(~scanf("%d%d",&n,&m)) {if(n==0&&m==0) break;memset(a,0,sizeof(a));for(int i = 1; i<=n; i++) {scanf("%d",&a[i]);}sort(a+1,a+n+1, greater<int>() );if(n<=m) {for(int i = 1; i<=n; i++) {printf("%d%c",a[i],i==n?'\n':' '); }continue;}if(n>m) {for(int i = 1; i<= m; i++) {printf("%d%c",a[i],i==m?'\n':' '); }}}return 0 ;
}
事实证明不加if(n<=m)的情况 也能ac,看来是样例中没出这样的样例?不然依照题干应该是有这一种情况发生啊。
优先队列ac:
#include<cstdio>
#include<iostream>
#include<queue>
using namespace std;
priority_queue<int,vector<int>,less<int> >q;//等价于priority_queue<int> q; 从大到小排序
int main()
{int n,t,a;while(scanf("%d %d",&n,&t)&&(n!=0||t!=0)){for(int i=0;i<n;i++){scanf("%d",&a);q.push(a);}for(int i=0;i<t-1;i++){printf("%d ",q.top());q.pop();}printf("%d",q.top());//最有一个数字没有空格。printf("\n");//每次别忘清空队列while(!q.empty()) q.pop();}return 0;
}
int n,t,a;while(scanf("%d %d",&n,&t)&&(n!=0||t!=0)){for(int i=0;i<n;i++){scanf("%d",&a);q.push(a);}for(int i=0;i<t-1;i++){printf("%d ",q.top());q.pop();}printf("%d",q.top());//最有一个数字没有空格。printf("\n");//每次别忘清空队列while(!q.empty()) q.pop();}return 0;
}
优先队列ac2:(优化了n<=m的情况)源自网络
/*
当输入小于m个的时候,一直输入,当输入大于m个数之后 ,这m个数会按照从小到大的顺序排序,
再往里面输入的时候要进行判断,如果那个数比对顶元素大的话,这个数进队,对顶元素出对,
进队后就又变成从小到大排序了,输入完毕之后,将数据按从大到小输出,因为对顶元素是最小值,
所以,应该将元素 都重新赋值到数组中,然后从后往前输出!(就这个转换方法必须想到!!!)
*/
#include <stdio.h>
#include <queue>
#include <algorithm>
using namespace std;
priority_queue<int,vector<int>,greater<int> >q;
int a,b[100005];
int main() {int n,m,i,j,k;while(scanf("%d%d",&n,&m)&&(n||m)) { //n,m分别代表村中的总人数,和最富有的前m个人for(i=0; i<n; i++) { //将财产值放到队列中scanf("%d",&a);if(q.size()<m)q.push(a);else if(a>q.top()) {q.push(a);q.pop();}}if(n>m) { //当总人数比富翁人数多的话执行下面语句for(i=0; i<m; i++) {b[i]=q.top();q.pop();}for(i=m-1; i>0; i--)printf("%d ",b[i]);printf("%d\n",b[0]);} else { //总人数没有富翁人数多的话,执行这个下面的语句!for(i=0; i<n; i++) {b[i]=q.top();q.pop();}for(i=n-1; i>0; i--)printf("%d ",b[i]);printf("%d\n",b[0]);}}return 0;
}
今天又用set实现了一下,,第一发错了,后来发现需要multiset
AC代码:
#include<bits/stdc++.h>using namespace std;
multiset<int,greater<int> > ss;
int main()
{int n,m;while(~scanf("%d%d",&n,&m) ) {if(n+m == 0) break; ss.clear();int tmp;for(int i =1; i<=n; i++) {scanf("%d",&tmp);ss.insert(tmp);}int cnt = 0;set<int, greater<int> > :: iterator it; for(it = ss.begin(); it!=ss.end(); it++) {cnt++;printf("%d%c",*it,cnt==m?'\n':' ');if(cnt == m) break;}}return 0 ;
}