非结构体的解题办法

成绩排序

http://www.nowcoder.com/questionTerminal/0383714a1bb749499050d2e0610418b1

用结构体定义数据组然后排序当然是个很灵巧的办法,但是实际上仍然需要反复比较和确认顺序,也没有那么灵活。
我的思路是,既然最终逃不过要排序,那无非是要解决两个核心问题:

1.不管升序排序还是降序排序,都必须实现稳定。
2.姓名必须跟随成绩一起换位。

我的解决思路是:
对于问题1,那就不管升序降序,都用稳定的直接插入排序进行升序排序,如果要求降序,那就用整体逆序+局部再逆序解决;

对于问题2,再建一个等大的数组new_ord,用这个数组来表示当前输出队列上每个成绩对应的姓名在初始姓名列表里的位置。排序的时候在修改score的同时捆绑修改new_ord

/*

***********************************************************************************************************************************************************************
代码的核心思想是:
 
1.读入个数num和升降序标志order;
2.建立二维数组name用以存储学生姓名,每一行表示一个姓名;建立一维数组score,存储学生成绩;
3.建立new_ord数组,用以存储当前每个score元素对应的学生姓名在name数组的行标。
 
    举个例子,假设刚读入数据后,name[0] = 张三,score[0] = 100,new_ord[0] = 0,即表示未排序之前,张三100分在第一位输入。
    排序之后,name[0] = 张三,score[3] = 100,new_ord[3] = 0,即表示排序之后,张三100分在第4位输出。为何如此与排序方式有关。
     
4.基于直接插入排序先对成绩进行升序排序,同时new_ord中的元素进行捆绑换位。
5.对order进行判断,如果是降序,则先进行一次整体逆置(score和new_ord都整体逆置)。再扫描整个score,对每一段分数相同的区间上的new_ord再分别进行逆置(因为直接插入排序是稳定的,所以直接区间逆置就行)
6.最后输出,name按照new_ord存储的元素行标顺序输出,score已经经过排序,直接输出。
 
***********************************************************************************************************************************************************************
*/
 
#include <cstdio>
 
void comparesort(int score[],int new_ord[],int num,int order){//基于直接插入排序对成绩进行稳定排序,同时对new_ord中元素进行捆绑换位
    int i,j,temps,tempn;
    for(i = 1; i < num; i++){
        if(score[i] < score[i-1]){
            temps = score[i];
            tempn = new_ord[i];
            for(j = i - 1; temps < score[j] && j>= 0;j--){
                score[j+1] = score[j];
                new_ord[j+1] = new_ord[j];
            }
            score[j+1] = temps;
            new_ord[j+1] = tempn;
        }
    }
    if(order == 0){
        for(i = 0; i <= num / 2 - 1; i++){//如果要求为降序,为了满足题意,需要先对score和new_ord先进行逆置,再针对每个同分数的部分进行逆置
            temps = score[i];
            score[i] = score[num-1-i];
            score[num-1-i] = temps;
            tempn = new_ord[i];
            new_ord[i] = new_ord[num-1-i];
            new_ord[num-1-i] = tempn;
        }
         
        int k;
        for(i = 0; i < num; i++){//对
            if(i + 1 < num && score[i] == score[i+1]){
                for(j = i + 1; score[j+1] == score[j]; j++);
                for(k = 0;i+k < j-k; k++){
                    tempn = new_ord[i + k];
                    new_ord[i + k] = new_ord[j - k];
                    new_ord[j - k] = tempn;
                }
                i = j++;
            }
 
        }
    }
}
 
 
int main(){
    int num,order;
    while(scanf("%d%d",&num,&order) != EOF){
        char name[num][20];
        int score[num];
        for(int i = 0;i < num; i++){
            scanf("%s %d",&name[i],&score[i]);
        }
        int new_ord[num];
        for (int i = 0; i < num; i++) new_ord[i] = i;
        comparesort(score,new_ord,num,order);
        for(int i = 0;i < num; i++)
            printf("%s %d\n",name[new_ord[i]],score[i]);
    }
    return 0;
}



全部评论

相关推荐

头像
不愿透露姓名的神秘牛友
03-13 14:57
点赞 评论 收藏
转发
1 收藏 评论
分享
牛客网
牛客企业服务