王道复试机试(2)

  • 比较问题,自定义compare

①学号姓名排名(用sort函数)

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;


struct Student
{
	int number;
	int score;
};
Student arr[100];

bool compare(Student x,Student y)
{
	if(x.score==y.score)
	{
		return x.number<y.number; //若x<y则true 
	}
	else
		return x.score<y.score;
}
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		scanf("%d%d",&arr[i].number,&arr[i].score);
	}
	sort(arr,arr+n,compare);
	for(int i=0;i<n;++i)
	{
		cout<<arr[i].number<<" "<<arr[i].score<<endl; 
	}
	return 0;
}

或者可以用运算符重载<的关系。

struct Student
{
	int number;
	int score;
	bool operator <(Student other) const
	{
		if(score==other.score)
			return number<other.number;
		else
			return socre<other.score;
	}	
};

②输入10个数字,奇数输出在前从大到小,偶数输出在后从小到大。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

int arr[10];
bool compare(int x,int y)
{
	if (x%2==1&&y%2==1) //都是奇数 
	{
		return y<x; //从大到小 
	}
	else if (x%2==0&&y%2==0) //都是偶数 
	{
		return x<y; //从小到大 
	}
	else if (x%2==1&&y%2==0) //x为奇,y为偶 
	{
		return true; //原本就应该奇数在前偶数在后
	}
	else
	{
		return false;
	}
}
int main()
{
	while(scanf("%d",&arr[0])!=EOF)
	{
		for(int i=1;i<10;i++)
		{
			scanf("%d",&arr[i]);
		}
		sort(arr,arr+10,compare); 
		for(int i=0;i<10;i++)
		{
			printf("%d ",arr[i]);
		}
		cout<<endl;
	}
	return 0;
}

在这里插入图片描述
2.sort(HDU 1425)
给n个整数,请你按从大到小顺序给出前m大的数范围为数字(-50000,50000),排序后的最后一个数字跟换行,之前的跟空格。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

const int MAXN=1e6+10;
const int RANGE=1e5;

int arr[MAXN]; //数组  1 5 -5 
int number[MAXN]; //辅助数组  50001,50005, 49995 

int main()
{
	int n,m; //n个数,m个数之前的 
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		memset(number,0,sizeof(number)); //多组样例输入重置数组 
		for(int i=0;i<n;i++)
		{
			scanf("%d",&arr[i]);
			number[arr[i]+RANGE]++; //存储数据出现的次数 
		}
		int index=0; 
		
		for(int i=0;i<MAXN;i++)//开始查询辅助数组中的次数 
		{
			while(number[i]--) 
			{
				arr[index++]=i-RANGE; //重建arr数组排序。 
			}
		}
		for(int i=n-1;i>=n-m;--i) //从大到小所以反着来 
		{
			if(i==n-m)
			{
				printf("%d\n",arr[i]);
			}
			else
			{
				printf("%d ",arr[i]);
			}
		} 
	}
	return 0;
}

在这里插入图片描述
3.逆序数对,归并排序

  • 逆序数对 2,8,0,4,3
    有(8,0),(8,4),(8,3),(4,3),则逆序数为4

  • 归并算法在这里插入图片描述

  • 归并代码

#include<iostream>
#include<cstdio>
using namespace std;

int arr[100];
int temp[100];
/*  1 2 5 6 7     3 4 7 8 9
    l       m     m+1      r     
    i             j             比较ij所指向的值生成新排序数组 
    
①  1         (i->[1],j->[0])
②  1 2       (i->[2],j->[0]) 
③  1 2 3     (i->[2],j->[1])
④  1 2 3 4    (i->[2],j->[2])  
*/
void combine(int left,int middle,int right)
{
	int i=left;
	int j=middle+1;
	int k=left;
	while(i<=middle && j<=right)
	{
		if(arr[i]<=arr[j])
		{
			temp[k++]=arr[i++]; //赋值完移动 
		}
		else
		{
			temp[k++]=arr[j++];
		} 
	}
	while(i<=middle)  //i可能未到头,把剩下的放进来 
	{
		temp[k++]=arr[i++]; 
	}
	while(j<=right)
	{
		temp[k++]=arr[j++];
	}
	for(k=left ;k<=right ;++k) //把temp值还给arr 
	{
		arr[k]=temp[k];
	} 
	return;
} 
void MergeSort(int left,int right)
{
	if(left<right) //还未分到小块 
	{
		int middle = left+(right-left)/2;
		MergeSort(left,middle);
		MergeSort(middle+1,right); //有序
		combine(left,middle,right); //合并 
	}
	return ;
}
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		scanf("%d",&arr[i]); 
	}
	MergeSort(0,n-1);
	for(int i=0;i<n;i++)
	{
		printf("%d ",arr[i]); 
	}
	printf("\n");
	return 0;
}

逆序数

int number;

void combine(int left,int middle,int right)
{
	while(i<=middle && j<=right)
	{
		if(arr[i]<=arr[j])
		{
			temp[k++]=arr[i++]; //赋值完移动 
		}
		else
		{
			temp[k++]=arr[j++];
			number+= miidle-i+1; //在这里计数
		} 
	}
  • 快速排序
#include<iostream>
#include<cstdio>
#include<stdlib.h>
using namespace std;
int arr[100];
int Partition(int left,int right)
{
	int random = left + rand() % (right-left);
	swap(arr[left],arr[random]); //随机生成的点作为left的点 
	while(left<right)
	{
		while(left<right&&arr[left]<=arr[right]) //左边<右边 右指针移动  
		{
			--right;
		}
		swap(arr[left],arr[right]); //直到移动不了,交换值 
		while(left<right&&arr[left]<=arr[right])//左边<右边 左边指针移动
		{
			++left;
		}
		swap(arr[left],arr[right]);//直到移动不了,交换值 
	}
	return left; //left和right一样的 
}
void QuickSort(int left,int right)
{
	if(left<right)
	{
		int position=Partition(left,right); //中心值的下标 
		QuickSort(left,position-1);
		QuickSort(position+1,right);
	}
} 
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;++i)
	{
		scanf("%d",&arr[i]);
	}
	QuickSort(0,n-1);
	for(int i=0;i<n;++i)
	{
		printf("%d ",arr[i]);
	}
	return 0;
}
  • 第K大数
#include<iostream>
#include<cstdio>
#include<stdlib.h>
using namespace std;
int arr[100];
int Partition(int left,int right)
{
	int random = left + rand() % (right-left);
	swap(arr[left],arr[random]); //随机生成的点作为left的点 
	while(left<right)
	{
		while(left<right&&arr[left]<=arr[right]) //左边<右边 右指针移动  
		{
			--right;
		}
		swap(arr[left],arr[right]); //直到移动不了,交换值 
		while(left<right&&arr[left]<=arr[right])//左边<右边 左边指针移动
		{
			++left;
		}
		swap(arr[left],arr[right]);//直到移动不了,交换值 
	}
	return left; //left和right一样的 
}
int QuickSort(int left,int right,int k)
{
	int position;
	if(left<right)
	{
		position=Partition(left,right); //中心值的下标 
		if(position==k-1)
			return arr[position];
		else if(position<k-1) //position小于k值则在右侧比她大的区间找k
		{
			return QuickSort(position+1,right,k); 
		} 
		else//position大于k值则在左侧比他小的区间找k
		{
			return QuickSort(left,position-1,k);
		}
	}
} 
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;++i)
	{
		scanf("%d",&arr[i]);
	}
	int k;
	scanf("%d",&k);
	
	printf("%d\n",QuickSort(0,n-1,k));
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值