排序2——2021-01-26更

昨天我已经写了排序1,今天接着写有关排序的题目。

排序2

T1 近似排序

题目:

有个人是从火星来的,在他世界里所有的数字都是反的,比如我们看到的30,在他看来却是3,我们看到的29,在他看来是92,因此他认为29是大于30的。

现在他拥有一个区间内的数字,请按照他的规则进行由小到大排序。

输入
一行,包含两个用空格隔开的自然数,这两个数给出了待排序数的范围,其中0<n<=m<1000000000,两个数之差不超过100。
输出
排序后的数据,每行一个数。
输入样例
22 39
输出样例
30
31
22
32
23
33
24
34
25
35
26
36
27
37
28
38
29
39

思路:

看到这道题的时候,我第一时间是觉得要用数学解法,因为m最大值竟然到了十亿,就算用数学解法也肯定会TLE,头脑风暴了一会儿后才看到n、m的差最大到100,于是事情就变得简单起来了。先把每个数的原数与火星人看到的数用结构体存起来,再手写一个bool函数判断,sort完了之后输出原数。

代码如下:

#include<bits/stdc++.h> 
using namespace std;
typedef unsigned long long ULL;
struct node
{
    
    
	ULL ys,jss;
}a[110];
int n,m,k;

int dx(int x)
{
    
    
	int s=0;
	while(x)
	{
    
    
		s=s*10+x%10;
		x/=10;
	}
	return s;
}
bool cmp(int q,int p)
{
    
    
	return q>p;
}
int main()
{
    
    
    cin>>n>>m;
    for(int i=n;i<=m;i++)
    {
    
    
    	a[++k].ys=i;
    	a[k].jss=dx(a[k].ys);
    }
    for(int i=1;i<=k;i++)
    {
    
    
    	for(int j=1;j<k;j++)
    	{
    
    
    		if(cmp(a[j].jss,a[j+1].jss))
    			swap(a[j],a[j+1]);
    	}
    }
	for(int i=1;i<=k;i++)
		cout<<a[i].ys<<endl;
	return 0;
} 

T2 分数线划定

题目:

世博会志愿者的选拔工作正在 A 市如火如荼的进行。为了选拔最合适的人才,A 市对所有报名的选手进行了笔试,笔试分数达到面试分数线的选手方可进入面试。面试分数线根据计划录取人数的 150%划定,即如果计划录取 m 名志愿者,则面试分数线为排名第 m*150% (向下取整)名的选手的分数,而最终进入面试的选手为笔试成绩不低于面试分数线的所有选手。

现在就请你编写程序划定面试分数线,并输出所有进入面试的选手的报名号和笔试成绩。

输入
第一行,两个整数 n,m(5 ≤ n ≤ 5000,3 ≤ m ≤ n),中间用一个空格隔开,其中 n 表示报名参加笔试的选手总数,m 表示计划录取的志愿者人数。输入数据保证 m*150% 向下取整后小于等于 n。

第二行到第 n+1 行,每行包括两个整数,中间用一个空格隔开,分别是选手的报名号 k (1000 ≤ k ≤ 9999)和该选手的笔试成绩 s(1 ≤ s ≤ 100)。数据保证选手的报名号各不相同。

输出
第一行,有两个整数,用一个空格隔开,第一个整数表示面试分数线;第二个整数为进入面试的选手的实际人数。

从第二行开始,每行包含两个整数,中间用一个空格隔开,分别表示进入面试的选手的报名号和笔试成绩,按照笔试成绩从高到低输出,如果成绩相同,则按报名号由小到大的顺序输出。
输入样例
6 3
1000 90
3239 88
2390 95
7231 84
1005 95
1001 88
输出样例
88 5
1005 95
2390 95
1000 90
1001 88
3239 88

思路:

这道题目其实不算太难,只要把分数线算出并且找到进入的人数就好了。

代码如下:

#include<bits/stdc++.h>
using namespace std;
long long n,m,k,s,f; 
struct node
{
    
    
	int xh,fs;
}a[100010];

bool cmp(node q,node p)
{
    
    
	if(q.fs==p.fs)//如果同分,则对比号数
		return q.xh<p.xh;
	return q.fs>p.fs;
}
int main()
{
    
    
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		cin>>a[i].xh>>a[i].fs;
	sort(a+1,a+1+n,cmp);
	k=1.5*m;
	s=a[k].fs;
	int j=0;//j存通过的人数
	while(a[j+1].fs>=s)
		j++;
	cout<<s<<" "<<j<<endl;	
	for(int i=1;i<=j;i++)
		cout<<a[i].xh<<" "<<a[i].fs<<endl;
	return 0;	
}

T3 车厢重组

题目:

在一个旧式的火车站旁边有一座桥,其桥面可以绕河中心的桥墩水平旋转。一个车站的职工发现桥的长度最多能容纳两节车厢,如果将桥旋转180度,则可以把相 邻两节车厢的位置交换,用这种方法可以重新排列车厢的顺序。于是他就负责用这座桥将进站的车厢按车厢号从小到大排列。

他退休后,火车站决定将这一工作自动 化,其中一项重要的工作是编一个程序,输入初始的车厢顺序,计算最少用多少步就能将车厢排序。
输入
有两行数据,第一行是车厢总数N(不大于10000),第二行是N个不同的数表示初始的车厢顺序。
输出
一个数据,是最少的旋转次数。
输入样例
4
4 3 2 1
输出样例
6

思路:

这道题目是一道很经典的题目,其实本质上就是让我们手写一个冒泡排序,每次交换的时候就把次数+1.

代码如下:

#include<bits/stdc++.h>
using namespace std;
int a[10010],n,f,h,k;
int main()
{
    
    
	cin>>n; 
	for(int i=1;i<=n;i++)
		cin>>a[i];
	for(int i=1;i<n;i++)
	{
    
    
		f=0;
		for(int j=1;j<n;j++)
		{
    
    
			if(a[j]>a[j+1])
			{
    
    
				swap(a[j],a[j+1]);
				h++;
				f++;
			}
		}
		if(f==0)//判定,当前已经无需交换时直接退出
			break;
	}	
	cout<<h;
	return 0;
}

T4 奖学金

题目:

某小学最近得到了一笔赞助,打算拿出其中一部分为学习成绩优秀的前5名学生发奖学金。期末,每个学生都有3门课的成绩:语文、数学、英语。先按总分从高到低排序,如果两个同学总分相同,再按语文成绩从高到低排序,如果两个同学总分和语文成绩都相同,那么规定学号小的同学排在前面,这样,每个学生的排序是唯一确定的。
任务:先根据输入的3门课的成绩计算总分,然后按上述规则排序,最后按排名顺序输出前5名学生的学号和总分。注意,在前5名同学中,每个人的奖学金都不相同,因此,你必须严格按上述规则排序。例如,在某个正确答案中,如果前两行的输出数据(每行输出两个数:学号、总分)是:
7 279
5 279
这两行数据的含义是:总分最高的两个同学的学号依次是7号、5号。这两名同学的总分都是279(总分等于输入的语文、数学、英语三科成绩之和),但学号为7的学生语文成绩更高一些。如果你的前两名的输出数据是:
5 279
7 279
则按输出错误处理。
输入
包含n+1行:
第1行为一个正整数n(n<=300),表示该校参加评选的学生人数。
第2到年n+1行,每行有3个用空格隔开的数字,每个数字都在0到100之间。第j行的3个数字依次表示学号为j-1的学生的语文、数学、英语的成绩。每个学生的学号按照输入顺序编号为1~n(恰好是输入数据的行号减1)。
所给的数据都是正确的,不必检验。

输出
共有5行,每行是两个用空格隔开的正整数,依次表示前5名学生的学号和总分。
输入样例
6
90 67 80
87 66 91
78 89 91
88 99 77
67 89 64
78 89 98
输出样例
6 265
4 264
3 258
2 244
1 237

思路:

这道题目其实我一开始做的时候踩了一个坑,导致我测试的数据一直都不正确,仔细检查了程序之后也没发现问题,后来再看了一次题目,才看见同分要按语文成绩来排(我就想知道,要是语文成绩也一样怎么办)。扯远了,现在说一下这道题目的思路,就是用一个结构体存一下语文成绩和三总,然后按分数由高到低排序,如果同分,就比语文成绩。

代码如下:

#include<bits/stdc++.h> 
using namespace std;
int n;
struct stu
{
    
    
    int sz,yw,xh;
}a[310];
bool cmp(stu q,stu p)
{
    
    
	if(q.sz==p.sz)
		return q.yw>p.yw;
	return q.sz>p.sz;	
}
int main()
{
    
        
	cin>>n;
	for(int i=1;i<=n;i++)
		a[i].xh=i;
	for(int i=1;i<=n;i++)
	{
    
    
	    int sx,yy;
		cin>>a[i].yw>>sx>>yy;
		a[i].sz=a[i].yw+sx+yy;
	} 
	sort(a+1,a+1+n,cmp);
	for(int i=1;i<=5;i++)
		cout<<a[i].xh<<" "<<a[i].sz<<endl;
	return 0;
}

排序系列——排序1

排序系列——排序3

猜你喜欢

转载自blog.csdn.net/SSL_wyd/article/details/113195797