相当于给出一组数列,然后选择前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; }
HDU 1031 Design T-Shirt 选前k大,布布扣,bubuko.com
原文地址:http://blog.csdn.net/kenden23/article/details/38711857