题目地址:1015 德才论 (25 分)&1020 月饼 (25 分)
题目解析:
1.这两道题目都是典型的分层级排序,利用qsort在comp中写明比较次序,很容易的就可以将题目解答。
2.qsort是PAT乙级当中多次需要用到的一个函数,非常方便。使用方式如下:
/*所在头函数库*/
#include<stdlib.h>
/*你需要的排序方式函数comp*/
int comp(const void *a,const void *b)//默认a=aa[i],b=aa[i+1]
{return *(int*)a-*(int*)b;} //将从小到大排
//或者 {return *(int*)b-*(int*)a;} 将从大到小排
/*使用的方式*/
int main()
{ qsort(aa,len,sizeof(int),comp);}
//aa为数组,len为你要从数组aa的首地址开始向后排列的范围(即aa[0]-aa[len-1])
//另{ qsort(aa+1,len-1,sizeof(int),comp);}(即aa[1]-aa[len-1])注意len是个数!
//sizeof(int),元素类型
//comp你写明的排序方式,
//若小于0则aa[i]在[i+1]的前面,若大于0则aa[i]在[i+1]的后面,等于0则不确定两者位置
我的代码:
德才论
#include<stdio.h>
#include<stdlib.h>
typedef struct stu
{
int id;
int mo;
int ab;
int rk;
int sum;
}s;
typedef s *sp;
int rank(sp ss, int min, int max);
int comp(const void *a, const void *b);
int main()
{
int n, min, max, tol = 0;
sp aa[100000];
scanf("%d %d %d", &n, &min, &max);
int idid, momo, abab;
for (int i = 0; i < n; i++)//正式读入数据
{
scanf("%d %d %d", &idid, &momo, &abab);
if (momo >= min && abab >= min)
{
sp news = (sp)malloc(sizeof(struct stu));
news->id=idid, news->mo=momo, news->ab=abab;
news->sum = momo + abab;
news->rk = rank(news, min, max);//给数据分级
aa[tol++] = news;
}
}
qsort(aa, tol, sizeof(sp), comp);//排序,注意这里的数组是结构体指针的数组,
//故 sizeof(sp)
printf("%d\n", tol);
for (int i = 0; i < tol; i++)//写出
{
printf("%d %d %d\n", aa[i]->id, aa[i]->mo, aa[i]->ab);
free(aa[i]);
}
return 0;
}
int rank(sp ss, int min, int max)//我们设定大数为优,划定等级
{
if (ss->mo >= max && ss->ab >= max) return 4;//德才兼备 为4
else if (ss->mo >= max) return 3; //德备才弱 为3
else if (ss->mo >= ss->ab) return 2; //德才兼弱而德胜才 为2
else return 1; //其余 为1
}
int comp(const void *a, const void *b)
{
sp s1 = *(sp*)a, s2 = *(sp*)b;//数据被转存出来,以供方便使用
if (s1->rk != s2->rk) return s2->rk - s1->rk; //先排列等级,由大到小排列
else if (s1->sum != s2->sum) return s2->sum - s1->sum; //等级同,比较总分
else if (s1->mo != s2->mo) return s2->mo - s1->mo; //总分同,比较德分
else return s1->id - s2->id; //德分同,比较ID,这里升序,由小到大排
}
月饼
#include<stdio.h>
#include<stdlib.h>
typedef struct eve
{
double v;
double box;
double mon;
}e;
typedef e *ep;
int comp(const void*a, const void*b);
int main()
{
double n, ne;
scanf("%lf %lf", &n, &ne);//读入,这道题的输入,得我们自己去领会到才行,神坑
ep aa[1000] = { NULL };
for (int i = 0; i < n; i++)//库存
{
ep np = (ep)malloc(sizeof(e));
scanf("%lf", &np->box);
aa[i] = np;
}
for (int i = 0; i < n; i++)//售价
{
scanf("%lf", &aa[i]->mon);
aa[i]->v = aa[i]->mon / aa[i]->box;
}
qsort(aa, n, sizeof(ep), comp);//排列单价,同样的结构体指针数组
double tol = 0.0, tolm = 0.0;
for (int i = 0; i < n; i++)//一种一种的加起来算钱钱
{
if (tol == ne)//刚好
{
printf("%.2lf", tolm);
return 0;
}
else if (tol < ne && tol + aa[i]->box <= ne)//供小于求,
{ //且加上本位仍不足或刚好,
tol += aa[i]->box; //就将本位加完
tolm += aa[i]->mon;
}
else if (tol < ne && tol + aa[i]->box > ne) //供小于求
{ //且加上本位会超过
tolm += ((ne - tol) / aa[i]->box)*aa[i]->mon; //我们需要仔细计算
printf("%.2lf", tolm);
return 0;
}
}
printf("%.2lf", tolm);
return 0;
}
int comp(const void*a, const void*b)
{
ep p1 = *(ep*)a, p2 = *(ep*)b;
double renum = p2->v - p1->v;//由大到小排列,由于是浮点数,所以
if (renum < 0.0)return -1; //在下面这里小心处理,不然舍进位会出大问题
else if (renum == 0.0)return 0;
else if (renum > 0.0)return 1;
}