风言枫语  

程序设计题:

3:有20个数组,每个数组有500个元素,并且是有序排列好的,现在在这20*500个数中找出排名前500的数

思路:可以先选出20个数组中最大的数,进行比较,选出其中最大的数,然后再从选出最大的那个数组中选出数放入20个数中比较,每次都重复步骤,直到最终选出500个数,这个复杂度是多少呢?

20个数的比较可以用堆,插入一个数lgn,故总的复杂度是500lg20

用这个思路写出代码如下:

 

vector< vector<int> > arr;
struct CNode
{

	CNode( int data, int num )
	{
		m_data = data;
		m_num  = num;
	}

	int m_data;
	int m_num;
};

struct CCmp
{
	bool operator()(const CNode &a, const CNode &b )
	{
		if ( a.m_data == b.m_data )
			return a.m_num < b.m_num;
		else 
			return a.m_data < b.m_data;
	}
};
void Test3()
{
	srand(time(NULL));
	arr.resize(20);
	for ( int i=0; i<20; ++i )
	{
		arr[i].resize(500);
		for ( int j=0; j<500; ++j )
			arr[i][j] = rand();

		sort( arr[i].begin(), arr[i].end() );
	}
	// 20 个排序好的数组
	priority_queue<CNode,vector<CNode>,CCmp> priq;
	for ( int i=0; i<20; ++i )
	{
		priq.push(CNode( arr[i].back(), i));
		arr[i].pop_back();
	}

	for ( int i=0; i<500; ++i )
	{
		CNode data = priq.top(); // 求出最大的
		priq.pop();
		cout<<i+1<<"th : "<< data.m_data<<endl;
		int num = data.m_num;
		priq.push( CNode( arr[num].back(), num) );
		arr[num].pop_back();
	}// 求出最大的500个

}

还可以有什么思路呢?我们可以知道每组中最大数和最小数,那此时就可以有个区间,那对20个区间进行排序,此时有几种情况呢?

 

此时根据上面的思路,我们可以对20段区间进行排序,然后从最大区间中开始找数,然后在找出最大的那些数后,将这些数删除,重新将排除大数的数的区间进行排序,然后重复以上步骤,直到找到500个数。


 

posted on 2013-09-21 13:09  风言枫语  阅读(252)  评论(0编辑  收藏  举报