相当于给出一组数列,然后选择前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;
}