- 比较问题,自定义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;
}