首页 > ACM题库 > HDU-杭电 > HDU 1280 前m大的数-线性结构-[解题报告] C++
2013
12-04

HDU 1280 前m大的数-线性结构-[解题报告] C++

前m大的数

问题描述 :

还记得Gardon给小希布置的那个作业么?(上次比赛的1005)其实小希已经找回了原来的那张数表,现在她想确认一下她的答案是否正确,但是整个的答案是很庞大的表,小希只想让你把答案中最大的M个数告诉她就可以了。
给定一个包含N(N<=3000)个正整数的序列,每个数不超过5000,对它们两两相加得到的N*(N-1)/2个和,求出其中前M大的数(M<=1000)并按从大到小的顺序排列。

输入:

输入可能包含多组数据,其中每组数据包括两行:
第一行两个数N和M,
第二行N个数,表示该序列。

输出:

对于输入的每组数据,输出M个数,表示结果。输出应当按照从大到小的顺序排列。

样例输入:

4 4
1 2 3 4
4 5
5 3 6 4

样例输出:

7 6 5 5
11 10 9 9 8


堆排第一道。。 开始一直wa。。 最后发现up和down都没递归

#include<stdio.h>
int num[30005],e[9000000],n,m,c;
inline void swap( int i,int j )
{
	e[i] ^= e[j] ^= e[i] ^= e[j];
}
void up( int c )
{
	if( c > 1 )
		if( e[c] > e[c/2] )
			swap( c,c/2 ),up( c / 2 );
}
void insert( int x )
{
	e[++c] = x;
	up( c );
}
inline void down( int q )
{
	int p = q * 2;
	if( p <= c )
	{
		if( p + 1 <= c )
			p = e[p] > e[p+1] ? p : ( p + 1 );
		if( e[p] > e[q] )
			swap( p,q ),down( p );
	}
}
int pop(  )
{
	int x = e[1];
	swap( 1,c-- );
	down( 1 );
	return x;
}
int main(  )
{
	while( scanf( "%d%d",&n,&m ) != EOF )
	{
		c = 0;
		for( int i = 0; i < n; ++i )
			scanf( "%d",&num[i] );
		for( int i = 0; i < n - 1; ++i )
			for( int j = i + 1; j < n; ++j )
				insert( num[i] + num[j] );
		for( int i = 0; i < m; ++i )
			printf( i == 0 ? "%d" : " %d",pop(  ) );
		puts( "" );
	}
	return 0;
}

  1. 第一句可以忽略不计了吧。从第二句开始分析,说明这个花色下的所有牌都会在其它里面出现,那么还剩下♠️和♦️。第三句,可以排除2和7,因为在两种花色里有。现在是第四句,因为♠️还剩下多个,只有是♦️B才能知道答案。