题意其实是求数组中的前k小的数。简单的方法大家都想得到,先排序,再取前k个,第二个不出意料的超时。要想以线性期望时间通过,应该得用随机选择算法来做。暂时先放着,以后再来解决。
代码:
#include<stdio.h> #include<stdlib.h> #include<string.h> const int MAXN = 100005; struct human{ char name[10]; int age; int net_worth; }rich[MAXN]; int cmp(const void *a,const void *b) { human *x=(human *)a; human *y = (human *)b; if(x->net_worth == y->net_worth && x->age == y->age) return strcmp(x->name, y->name); if(x->net_worth == y->net_worth) return x->age - y->age; return y->net_worth - x->net_worth; } int main() { int nPeople, nQuery, nOutput, aMin, aMax; int i,j; freopen("C:\\Documents and Settings\\Administrator\\桌面\\input.txt","r",stdin); scanf("%d%d",&nPeople, &nQuery); for(i = 0; i < nPeople; i++){ scanf(" %s%d%d",rich[i].name, &rich[i].age, &rich[i].net_worth); } qsort(rich, nPeople, sizeof(rich[0]), cmp); // for(i = 0; i < nPeople; i++){ // printf("%s %d %d\n",rich[i].name, rich[i].age, rich[i].net_worth); // // } int res; for(j = 0; j < nQuery; j++){ scanf("%d%d%d",&nOutput, &aMin, &aMax); printf("Case \#%d:\n", j+1); res = 0; for(i = 0; i < nPeople && res < nOutput; i++){ if(rich[i].age >= aMin && rich[i].age <= aMax){ printf("%s %d %d\n",rich[i].name, rich[i].age, rich[i].net_worth); res++; } } if(res == 0) printf("None\n"); } return 0; }