PAT甲题题解-1055. The World's Richest (25)-终于遇见一个排序的不水题

题目简单,但解题的思路需要转换一下,按常规思路肯定超时,推荐~

题意:给出n个人的姓名、年龄和拥有的钱,然后进行k次查询,输出年龄在[amin,amx]内的前m个最富有的人的信息。
如果财富值相同就就先输出年龄小的,如果年龄相同就按照名字的字典序排序输出~

n范围为10^5,所以显然不能每次查询的时候for一遍所有人,把符合条件的选出来再排序输出,这样肯定会超时。

但是注意到年龄的范围只有200,而且最后查询也跟年龄区间有关,那么有什么办法每次查询我只要取在这个年龄段里的人就好。
这样就想到用vector数组,vector node[i]存储所有年龄为i的人,且已经从大到小排好序。
那么对于要找[amin,amax]之间的前m个人,只要每次for一遍node[amin]~node[amax],比较每个node[i]的第一个,找出最大的输出,循环m次即可。
时间复杂度为k*m*[amax-amin],即O(1000*100*200)

 

#include <iostream>
#include <cstdio>
#include <string.h>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn=205;
struct Node{
    char name[10];
    int age;
    int worth;
};
bool cmp(Node a,Node b){
    if(a.worth==b.worth){
        if(a.age==b.age){
            if(strcmp(a.name,b.name)<=0)
                return true;
            else
                return false;
        }
        else
            return a.age<b.age;
    }
    else
        return a.worth>b.worth;
};
vector<Node> node[maxn]; //索引为年龄,node[i]存储年龄为i的人
int main()
{
    int n,k;
    scanf("%d %d",&n,&k);
    Node p;
    for(int i=0;i<n;i++){
        scanf("%s %d %d",p.name,&p.age,&p.worth);
        node[p.age].push_back(p);
    }
    for(int i=1;i<maxn;i++){
        sort(node[i].begin(),node[i].end(),cmp);
    }
    int m,amin,amax;
    int idx[maxn]; //记录每个node[i]参与比较的第一个位置
    int num;
    for(int i=0;i<k;i++){
        scanf("%d %d %d",&m,&amin,&amax);
        Node maxNode;
        maxNode.worth=-10000000;
        num=0;//统计有没有人,没有的话输出None
        int maxid;
        memset(idx,0,sizeof(idx));
        printf("Case #%d:\n",i+1);
        //因为要找出前m个,所以for循环m次,每次找出当前最大的一个
        for(int j=1;j<=m;j++){
            maxNode.worth=-10000000;
            maxid=-1;
            //在年龄范围内找出最大的,由于已经从大到小排好序,所以每次只要比较每个vector的第一个即可,其中最大的便肯定是范围内最大的
            for(int g=amin;g<=amax;g++){
                if(idx[g]<node[g].size()){
                    if(cmp(node[g][idx[g]],maxNode)){
                        maxNode.age=node[g][idx[g]].age;
                        maxNode.worth=node[g][idx[g]].worth;
                        strcpy(maxNode.name,node[g][idx[g]].name);
                        maxid=g;
                    }
                }
            }
            if(maxid==-1)
                break;
            num++;
            printf("%s %d %d\n",node[maxid][idx[maxid]].name,node[maxid][idx[maxid]].age,node[maxid][idx[maxid]].worth);
            idx[maxid]++; //找到最大的输出了,所以索引要++,下一次就比较该vector的下一个元素了。
        }
        if(num==0)
            printf("None\n");
    }
    return 0;
}
View Code

 

posted @ 2017-03-08 19:18  辰曦~文若  阅读(458)  评论(0编辑  收藏  举报