随笔- 23  评论- 0  文章- 0 

PAT1012

整体思路

  这道题看下来就是比较简单的模拟题,穿插了对排序和查找的考察。

  (1)存储:由于一个学生对象是有ID以及多个成绩信息,所以用自定义的结构体student来存储信息。多个学生就使用一个结构体数组stu来存储。

  (2)排序:我们调用<algorithm>库中的sort函数,基本就是O(nlogn)的复杂度,自己写个描述排序规则的cmp函数即可。排序完,整个std数组就会按照我们的规则乖乖排好了,因为我们会有多次排序,所以每一次的排序结果都要记录下来,那这个时候每一次排序结果要存储在哪里??就是一个问题,这个问题也是这道题的一个难点,这直接关系到下一个步骤——查找的效率!!

   好啦,想想我们是靠什么来查找的呢??是学生的ID号对吧,如果我们查找的时候能够按照ID号来对号入座,使用hash的方法,那时间复杂度就为O(n),即使在全部人都要一起来查找的情况下,算法也有很好的表现,对比起暴力查找方法O(n^2),简直就是人生赢家有木有(手动狗头)

  (3)查找:如此一来,在解决完排序的存储方式问题后,查找就是很自然的事,直接就用ID去哈希一下就OK啦!

避坑指南

  这道题还是有一丢丢的小坑的,不得不说细节还是很重要的,平时多练多总结,见得多的,练的熟了,自然避坑能力就会逐渐提高。

  (1)排名的方式:12225(✔)   12223(❌)

  (2)sort天坑:自己定义的cmp一定要使用 < 或者 > ,严格的大于小于,而不是<= ,>=,不然段错误就在前面等你,头铁定位了半天,检查各种循环边界条件和指针、数组索引,结果居然是你——一个 >= !!!气到呕血。。。 有机会的话,写一篇详细探究这个问题的博客。

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
//按照ACME顺序排列就不会有问题 
struct student{
    int id;
    int grade[4]; 
}stu[2010];
int now=0;
/*
记忆方法:sort实现升序排序,cmp函数的意义就是结果为真,放到前面 
*/ 
bool cmp(student s1,student s2){  //升序降序真的是个混乱的坑,得想办法搞好 
    return s1.grade[now] > s2.grade[now];  //!!!写成>=会造成段错误 
}

int rank_map[1000000][4];  //模拟哈希 

int main()
{
    freopen("in.txt","r",stdin);
    memset(rank_map,0,sizeof(rank_map));
    int stu_num;
    int che_num;
    scanf("%d %d",&stu_num,&che_num);
    for(int i=0;i<stu_num;++i){
        scanf("%d %d %d %d",&stu[i].id,&stu[i].grade[1],&stu[i].grade[2],&stu[i].grade[3]);
        stu[i].grade[0]=(stu[i].grade[1]+stu[i].grade[2]+stu[i].grade[3])/3;
    }

    for(now=0;now<4;++now){
        sort(stu,stu+stu_num,cmp);  //排序 
        //存储 
        int r=1;
        rank_map[stu[0].id][now]=r;
        for(int j=1;j<stu_num;++j){  //如果stu_num==0,是不是!=stu_num会死循环 
            if(stu[j].grade[now]!=stu[j-1].grade[now])
                r=j+1;
            rank_map[stu[j].id][now]=r;
        }
    }
    //查找 
    char c[5]={'A','C','M','E'}; 
    int check;
    for(int i=0;i!=che_num;++i){
        scanf("%d",&check);
        if(i!=0)
            printf("\n");
        if(rank_map[check][0]==0) 
            printf("N/A");
        else {
            int min=0;
            int min_num=rank_map[check][0];
            for(int j=1;j<4;++j){
                if(rank_map[check][j]<min_num){
                    min=j;
                    min_num=rank_map[check][j];
                }
            }
            printf("%d %c",min_num,c[min]);
        }
    }
    return 0;
}

 

posted on 2019-09-20 11:49  川川——叮叮咚咚  阅读(...)  评论(... 编辑 收藏