强化阶段 Day 7 算法笔记 4.1 排序

目录

1.选择排序

2.插入排序

3.排序题

3.1结构体的定义

3.2cmp函数

3.2.1strcmp函数以及字典序

3.2排名

​4.PAT Ranking 

5.Talent and Virtue

6.The Best Rank

7.Phone Bills


1.选择排序

void selectsort(){
	//n次循环,每次都会使有序长度加一 
	for(int i=1;i<=n;i++){
		//k代表的是最小元素的下标,在[i,n]的区间中,先让k为左端点i 
		int k = i;
		//不断和后面的元素比较,找到最小的元素下标 
		for(int j=i+1;j<=n;j++){
			if(a[j]<a[k]){
				k = j;
			}
		}
		//交换i位置和最小元素的位置,也就是k 
		int temp=a[i];
		a[i] = a[k];
		a[k] = temp;
	}
}

2.插入排序

void insertsort(){
	//[2,n]区间的元素进行排序 
	for(int i=2;i<=n;i++){
		//用pos和temp分别记录此次需要排序的坐标和值 
		int temp=martix[i],pos=i;
		//如果pos前一个位置的值大于pos所在的值,那么pos往前移动,该值则往后移动到pos所在的位置
		//因为区间是[1,n].所以pos-1要大于等于1,所以pos要大于1
		while(temp<martix[pos-1]&&pos>1){
			martix[pos] = martix[pos-1];
			pos--;
		}
		//已经找到pos的位置,将该位置设置为一开始记录的temp值 
		martix[pos] = temp;
	}
}

3.排序题

3.1结构体的定义

3.2cmp函数

3.2.1strcmp函数以及字典序

3.2排名

4.PAT Ranking 

遇到了一个很奇怪的bug,num++的位置

#include<cstdio>
#include<vector>
#include<cstring>
#include<stack>
#include<set>
#include<queue>
#include<algorithm>
using namespace std;

struct student{
	char id[15];
	int score;
	int loc_num;
	int final_rank;
	int local_rank;
}stu[30005];

bool cmp(student a,student b){
	//如果分数不同,那么分数高的在前面 
	if(a.score!=b.score) return a.score>b.score;
	//如果分数相同,那么字典序小的在前面 
	else return strcmp(a.id,b.id)<0;
}

int main(){
	//考场数 
	int n;
	scanf("%d",&n);
	
	int loc,num=0;
	for(int i=0;i<n;i++){
		//考场号 
		scanf("%d",&loc);
		//对该考场考生的信息进行输入,顺便根据i的值把考场号输入 
		for(int j=0;j<loc;j++){
			scanf("%s %d",&stu[num].id,&stu[num].score);
			stu[num].loc_num=i+1;
			num++;
		}
		//以下是对该考场的考生进行排序
		//loc_start是该考场第一个考生在该结构体数组中的位置坐标,而num则是最后一个考生坐标+1 
		int loc_start = num-loc;
		sort(stu+loc_start,stu+num,cmp);
		stu[loc_start].local_rank=1;
		//记录名次 
		for(int j=loc_start+1;j<num;j++){
			if(stu[j].score==stu[j-1].score) stu[j].local_rank=stu[j-1].local_rank;
			else stu[j].local_rank = j-loc_start+1;
		}
	}
	//对整体进行排序,求最终名次 
	sort(stu,stu+num,cmp);
	stu[0].final_rank=1;
	for(int i=1;i<num;i++){
		if(stu[i].score==stu[i-1].score) stu[i].final_rank=stu[i-1].final_rank;
		else stu[i].final_rank=i+1;
	}
	
	printf("%d\n",num);
	for(int i=0;i<num;i++){
		printf("%s %d %d %d\n",stu[i].id,stu[i].final_rank,stu[i].loc_num,stu[i].local_rank);
	}
	
	return 0;
}

5.Talent and Virtue

#include<cstdio>
#include<vector>
#include<cstring>
#include<stack>
#include<set>
#include<queue>
#include<algorithm>
using namespace std;
//创建cate属性,用来标记是圣人,君子或者其他,排序时作为第一标准 
struct per{
	char id[10];
	int vir;
	int tal;
	int cate;
}martix[100005];
//通过low和high确定每一个人是什么身份 
int low,high;
int get_cate(int vir,int tal){
	if(vir<low||tal<low) return 5;
	else if(vir>=high&&tal>=high) return 1;
	else if(tal<high&&vir>=high) return 2;
	else if(vir<high&&tal<high&&vir>=tal) return 3;
	else return 4;
}
//四层比较,分别是身份,总分,德以及名字的字典序 
bool cmp(per a,per b){
	if(a.cate!=b.cate) return a.cate<b.cate;
	else if(a.tal+a.vir!=b.tal+b.vir) return a.tal+a.vir>b.tal+b.vir;
	else if(a.vir!=b.vir) return a.vir>b.vir;
	else return strcmp(a.id,b.id)<0;
}

int main(){
	
	int n;
	scanf("%d %d %d",&n,&low,&high);
	//num用来统计需要排序的数量 
	int num=0;
	//输入的同时计算cate,并计算num 
	for(int i=0;i<n;i++){
		scanf("%s %d %d",&martix[i].id,&martix[i].vir,&martix[i].tal);
		martix[i].cate=get_cate(martix[i].vir,martix[i].tal);
		if(martix[i].cate!=5){
			num++;
		}
	}
	
	printf("%d\n",num);
	//对整个数组进行排序,最后前num个就是我们要输出的
	//因为不参加排序的因为cate最大,在数组的最后面
	sort(martix,martix+n,cmp);
	for(int i=0;i<num;i++){
		printf("%s %d %d\n",martix[i].id,martix[i].vir,martix[i].tal);
	}
	
	return 0;
}

6.The Best Rank

这一题的难点在于要从多个维度进行排序,最后将结果存储到另外一个数组中

#include<cstdio>
#include<vector>
#include<cstring>
#include<stack>
#include<set>
#include<queue>
#include<algorithm>
using namespace std;

//为了下面分别对四个成绩进行排序记录排名,用数组存储成绩 
struct stu{
	int id;
	int grade[4];
}martix[2005];

//第一维是考生号,第二维代表四个科目 
//即,横坐标为名字,纵坐标分别为四个成绩的排名 
int ranks[1000005][4]={0};
char course[4] = {'A','C','M','E'};

//now代表目前进行排序排名的科目 
int now;
bool cmp(stu a,stu b){
	return a.grade[now]>b.grade[now];
} 

int main(){
	
	int n,m;
	scanf("%d %d",&n,&m);
	//用总分代表平均分,避免进位的麻烦 
	for(int i=0;i<n;i++){
		scanf("%d %d %d %d",&martix[i].id,&martix[i].grade[1],&martix[i].grade[2],&martix[i].grade[3]);
		martix[i].grade[0] = martix[i].grade[1]+martix[i].grade[2]+martix[i].grade[3];
	}
	//分别从四个维度进行排序,并记录排名到rank数组中 
	for(now=0;now<4;now++){
		sort(martix,martix+n,cmp);
		ranks[martix[0].id][now] = 1;
		for(int j=1;j<n;j++){
			int pos=martix[j].id;
			if(martix[j].grade[now]==martix[j-1].grade[now]) ranks[pos][now] =ranks[martix[j-1].id][now];
			else ranks[pos][now] = j+1;
		}
	}
	
	int name;
	for(int i=0;i<m;i++){
		scanf("%d",&name);
		int ans,best=100000000;
		if(ranks[name][0]==0) printf("N/A\n");
		else{
			//找出最高的排名 
			for(int j=0;j<4;j++){
				if(ranks[name][j]<best){
					best = ranks[name][j];
					ans = j;
				}
			}
			printf("%d %c",ranks[name][ans],course[ans]);
			if(i!=m-1) printf("\n");
		}
	}
	
	return 0;
}

7.Phone Bills

这一题顶级逻辑题了,两个月前的我看都看不懂题解,今天能看得懂题解了,算是一种进步吧。

#include<cstdio>
#include<vector>
#include<cstring>
#include<stack>
#include<set>
#include<queue>
#include<algorithm>
using namespace std;

struct rec{
	char name[22];
	int MM,dd,hh,mm;
	bool sta;
}martix[1005],temp;

bool cmp(rec a,rec b){
	int flag=strcmp(a.name,b.name);
	if(flag!=0) return strcmp(a.name,b.name)<0;
	else if(a.MM!=b.MM) return a.MM<b.MM;
	else if(a.dd!=b.dd) return a.dd<b.dd;
	else if(a.hh!=b.hh) return a.hh<b.hh;
	else return a.mm<b.mm;
}

int charge[24];
void get_ans(int on,int off,int &time,int &money){
	temp = martix[on];
	while(temp.dd<martix[off].dd||temp.hh<martix[off].hh||temp.mm<martix[off].mm){
		time++;
		money+=charge[temp.hh];
		temp.mm++;
		if(temp.mm>=60){
			temp.mm=0;
			temp.hh++;
		}
		if(temp.hh>=24){
			temp.hh=0;
			temp.dd++;
		}
	}
}

int main(){
	
	for(int i=0;i<24;i++){
		scanf("%d",&charge[i]);
	}
	int n;
	scanf("%d",&n);
	char status[10];
	for(int i=0;i<n;i++){
		scanf("%s %d:%d:%d:%d %s",&martix[i].name,&martix[i].MM,&martix[i].dd,&martix[i].hh,&martix[i].mm,status);
		if(strcmp(status,"on-line")==0){
			martix[i].sta=true;
		}else{
			martix[i].sta=false;
		}
	}
	sort(martix,martix+n,cmp);
	//on为某人某次通话开始的位置,off为结束位置,next为下个人开始的位置 
	int on=0,off,next;
	while(on<n){
		
		int needprint=0;
		next = on;
		//如果某个人的一系列记录里,既有on又有off,那么说明需要输出,用needprint==2表示
		//在这个过程中,如果 strcmp(martix[next].name,martix[on].name)!=0成立了,那么说明next就是另外一个人的开始处 
		while(next<n&&strcmp(martix[next].name,martix[on].name)==0){
			if(needprint==0&&martix[next].sta==true){
				needprint=1;
			}else if(needprint==1&&martix[next].sta==false){
				needprint=2;
			}
			next++;
		}
		//如果某个人不需要输出,那么on就到下个人的开始处继续开始,continue直接跳出循环 
		if(needprint<2){
			on = next;
			continue;
		}
		//如果某个人需要输出,那么开始计算这个人所有的记录
		//注意,目前只是知道需要输出,但是需要输出几段还不清楚 
		int allmoney=0;
		printf("%s %02d\n",martix[on].name,martix[on].MM);
		//在这个人所有的记录里开始操作,每次循环都输出一次记录 
		while(on<next){
			//如果有连着的on和off那么就跳出循环,此时的on就是这个on-line的位置 
			while(on<next-1&&!(martix[on].sta==true&&martix[on+1].sta==false)){
				on++;
			}
			off=on+1;
			//如果off已经到了下个人的记录了,就可以跳出了 
			if(off==next){
				on=next;
				break;
			}
			printf("%02d:%02d:%02d ",martix[on].dd,martix[on].hh,martix[on].mm);
			printf("%02d:%02d:%02d ",martix[off].dd,martix[off].hh,martix[off].mm);
			int time=0,money=0;
			get_ans(on,off,time,money);
			allmoney += money;
			printf("%d $%.2f\n",time,money/100.0);
			//这个人的某对记录处理完毕,进入下一对记录的循环 
			on = off + 1;
		}
		printf("Total amount: $%.2f\n",allmoney/100.0);
	}
	
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值