经典入门_排序

例2.10 查找学生信息 (1069)

题目描述:输入N个学生的信息,然后进行查询。
输入: 输入的第一行为N,即学生的个数(N<=1000),接下来的N行包括N个学生的信息,然后输入一个M(M<=10000),接下来会有M行,代表M次查询,每行输入一个学号。
输出: 输出M行,每行包括一个对应于查询的学生的信息。如果没有对应的学生信息,则输出“No Answer!”
样例输入:
4
01 李江 男 21
02 刘唐 男 23
03 张军 男 19
04 王娜 女 19
5
02
03
01
04
03
样例输出:
02 刘唐 男 23
03 张军 男 19
01 李江 男 21
04 王娜 女 19
03 张军 男 19

这道题如果采用线性遍历数组来查找是否存在我们需要的元素,那么该算法的时间复杂度达到了O(n*m),而这已达到了千万数量级,是我们不愿意看到的。

利用二分查找,原来O(n*m)的时间复杂度被优化到O(nlogn(排序)+mlogn),符合我们的要求。

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct Student{
    char name[100];
    char sex[5];
    int age;
    char no[100];
    bool operator <(const Student &B)const{
        return strcmp(no,B.no)<0;
    }
}buf[1000];
int main(){
    int n;
    while(scanf("%d",&n)!=EOF){
        for(int i=0;i<n;i++){
            scanf("%s%s%s%d",buf[i].no,buf[i].name,buf[i].sex,&buf[i].age);
        }
        sort(buf,buf+n);
        int m;
        scanf("%d",&m);
        while(m--){
            char x[100];
            scanf("%s",x);
            int ans=-1;//目标下标 
            int top=n-1;//结束下标 
            int base=0;//开始下标 
            while(top>=base){//二分查找 
                int mid=(top+base)/2;
                int tmp=strcmp(buf[mid].no,x);
                if(tmp==0){
                    ans=mid;
                    break;
                }
                else if(tmp>0) top=mid-1;
                else base=mid+1; 
            }
            if(ans==-1) printf("No Answer!\n");
            else printf("%s %s %s %d\n",
            buf[ans].no,buf[ans].name,buf[ans].sex,buf[ans].age); 
        }
    }
    return 0;
}

 

posted @ 2018-02-05 02:28  Johnny、  阅读(108)  评论(0编辑  收藏  举报