【编码】对qsort函数的稳定排序优化-京东实习笔试编程题(一)-2016.04.08

 今晚在做京东的笔试题时,使用了qsort函数,由于排序结果不稳定,导致一直无法ac。后来在待排序的结构体中多加入一个关键字段,较简单的解决了问题。

题目:

生日礼物
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Problem Description:
BF的生日快到了,这一次,小东决定为BF送一份特别的生日礼物为其庆生。作为高智商中的佼佼者,BF在国外求学,因此小东无法与之一起庆生。小东计划送一个生日卡片,并通过特别的包装让BF永远难忘。

她决定把卡片套装在一系列的信封A = {a1,  a2,  ...,  an}中。小东已经从商店中购买了很多的信封,她希望能够用手头中尽可能多的信封包装卡片。为防止卡片或信封被损坏,只有长宽较小的信封能够装入大些的信封,同尺寸的信封不能套装,卡片和信封都不能折叠。

小东计算了邮寄的时间,发现她的时间已经不够了,为此找你帮忙包装,你能帮她吗?
输入
输入有若干组,每组的第一行包含三个整数n, w, h,1<=n<=5000, 1<=w, h<=10^6,分别表示小东手头的信封数量和卡片的大小。紧随其后的n行中,每行有两个整数wi和hi,为第i个信封的大小,1<=wi, hi<=10^6。
输出
对每组测试数据,结果第一行中输出最多能够使用的信封数量,结果第二行中按使用顺序输出信封的编号。由于小东有洁癖,她对排在前面的信封比较有好感,若有多个信封可用,她喜欢用最先拿到的信封。另外别忘了,小东要求把卡片装入能够装的最小信封中。
如果卡片无法装入任何信封中,则在单独的行中输出0。

样例输入
2 1 1
2 2
2 2
3 3 3
5 4
12 11
9 8​
样例输出
1
1
3
1 3 2​


我的代码:

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
  
using namespace std;

struct g
{
    int l;
    int w;
    int xu;
    bool tag;
}sticks[5000];

int cmp(const void *a,const void *b)
{
    struct g *c=(g *)a;
    struct g *d=(g *)b;
    if(c->l!=d->l)
        return c->l-d->l;
    else if(c->w!=d->w)
        return c->w-d->w;
    else
        return c->xu-d->xu;
}
/*
int swap(int &a,int &b){
    int t=a;
    a=b;
    b=t;
    return 0;
}

int partition(int* array,int left,int right)
{
    int index = left;
    int pivot = array[index];
    swap(array[index], array[right]);
    for(int i=left; i<right; i++)
    {
    if(array[i] < pivot)// 降序
        swap(array[index++], array[i]);
    }
    swap(array[right], array[index]);
    return index;
}

void qsort(int* array, int left, int right)
{
    if(left >= right)
        return;
    int index = partition(array, left, right);
    qsort(array, left, index - 1);
    qsort(array, index + 1, right);
}*/
  
int main()
{
    int i,j,n;
    int ans,temp;
    struct g card;
    while(cin>>n>>card.l>>card.w){
        //if(scanf("%d%d%d",&n,&card.l,&card.w)==1)
        for(i=0;i<n;i++)
        {
            sticks[i].tag=false;
            sticks[i].xu=i+1;
            scanf("%d%d",&sticks[i].l,&sticks[i].w);
        }
                        
        for(i=0;i<n;i++)
        {
            sticks[i].tag=false;
            printf("%d %d %d\n",sticks[i].l,sticks[i].w,sticks[i].xu);
        }

        qsort(sticks,n,sizeof(sticks[0]),cmp);//

        for(i=0;i<n;i++)
        {
            sticks[i].tag=false;
            printf("%d %d %d\n",sticks[i].l,sticks[i].w,sticks[i].xu);
        }
        ans=0;
        int xuhao[5000];
        for(i=0;i<n;i++)
        {
            if(sticks[i].tag==false)
            {
                    if(sticks[i].w>card.w&&sticks[i].l>card.l){
                        xuhao[ans]=sticks[i].xu;
                        ans++;
                        sticks[i].tag=true;
                    }    
                    else
                        continue;

                    temp=sticks[i].w;
                    for(j=i+1;j<n;j++)
                    {
                        if(sticks[j].tag==false&&sticks[j].w>temp)
                        {
                            xuhao[ans]=sticks[j].xu;
                            ans++;
                            sticks[j].tag=true;
                            temp=sticks[j].w;
                        }
                        //printf("%d\n",ans);
                    }
                    printf("%d\n",ans);
                    for(int j=0;j<ans;j++){
                        printf("%d ",xuhao[j]);
                    }
                    printf("\n");
                    break;
            }
        }
    }
    return 0;
}

对qsort函数的稳定优化

在调试时发现一个问题:qsort的结果不稳定,导致对于一些存在相等信封的测试用例输出错误。
优化方法:在待排序的结构体g中加入互不相等的属性:序号xu,即输入结构体的顺序。
在cmp函数中加入第三级关键字xu。很简单的避免了不稳定的情况。

struct g
{
    int l;
    int w;
    int xu;
    bool tag;
}sticks[5000];

int cmp(const void *a,const void *b)
{
    struct g *c=(g *)a;
    struct g *d=(g *)b;
    if(c->l!=d->l)
        return c->l-d->l;
    else if(c->w!=d->w)
        return c->w-d->w;
    else
        return c->xu-d->xu;
}

如果在排序后再进行稳定化处理,无疑要麻烦很多。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值