PAT (Basic Level) Practice (中文)1015 德才论 (25 分)&1020 月饼 (25 分)(25 分)_C语言实现

题目地址: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;
}

 

猜你喜欢

转载自blog.csdn.net/qq_43269246/article/details/84888537
今日推荐