今晚在做京东的笔试题时,使用了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;
}
如果在排序后再进行稳定化处理,无疑要麻烦很多。