首页 > 代码库 > HDU 1031 Design T-Shirt 选前k大

HDU 1031 Design T-Shirt 选前k大

相当于给出一组数列,然后选择前K大的数的算法。

本题没有给出详细的数据,故此就使用动态分配空间的方法了。

而这种题最好的算法就是使用快排思想,期望时间效率就是O(n)了。

最基本入门解决这种题的算法是直接排序了。那就成了水代码了。用上快排的思想才能体现出水平。

不过这种快排实在考的太多了,建议一定要掌握。

每次做这个算法的题目总会要调试一定时间的,每次都出现奇葩的错误。看来还是不够细心。

做题的时候一定要排除杂念,有干扰,后果很严重,会花长很多时间。

靖空间做题,一定要静,达到一种禅的境界。说禅是有点太玄了,不过取其静的意境罢了。


#include <stdio.h>
#include <vector>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;

int selectK(pair<int, double> arr[], int n, int k)
{
	pair<int, double> &pivot = arr[n-1];
	int j = 0;
	for (int i = 0; i+1 < n; i++)
	{
		if (arr[i].second > pivot.second ||
			(arr[i].second == pivot.second && arr[i].first < pivot.first))
		{
			swap(arr[i], arr[j++]);
		}
	}
	swap(arr[n-1], arr[j++]);//arr[j++] = pivot;逻辑错误
	if (j == k) return j;
	if (j - 1 == k) return j-1;
	else if (j < k) return selectK(arr + j, n - j, k - j);
	return selectK(arr, j-1, k);	//j > k
}

int main()
{
	int N, M, K;
	double a;
	while (~scanf("%d %d %d", &N, &M, &K))
	{
		pair<int, double> *arr = new pair<int, double>[M];
		for (int i = 0; i < M; i++)
		{
			arr[i].second = 0;
			arr[i].first = i;
		}
		for (int i = 0; i < N; i++)
		{
			for (int j = 0; j < M; j++)
			{
				scanf("%lf", &a);
				arr[j].second += a;
			}
		}

		selectK(arr, M, K);//M写成N错误。太不小心了!

		bool *indices = new bool[M];
		memset(indices, 0, sizeof(bool) * M);
		for (int i = 0; i < K; i++)
		{
			indices[arr[i].first] = true;
		}
		int c = 0;
		for (int i = M-1; i >= 0; i--)
		{
			if (indices[i])
			{
				if (c) putchar(' ');
				printf("%d", i+1);
				c++;
				if (c >= K) break;
			}
		}
		putchar('\n');
		delete [] arr;
		delete [] indices;
	}
	return 0;
}