题目传送门
这个题目是一个排序的模板题,可以使用和的算法通过,我这里讲三种方法(sort,归并和桶)。
sort:
没啥好讲的,直接调用就行了。
桶排序:
思路:
用普通的数组做桶肯定会爆,但是别忘了,c++里有一个叫STL的东西,而STL里又有一个叫map的东西,而map有非常适合做桶,map在第一次使用一个下标的时候才会生成这个下标对应的数,而且默认为零,这样,就不用担心会爆的问题啦。
代码:
要开c++11呦,否则会报错······
#include<iostream>
#include<map>
using namespace std;
map<int,int> a;
int n;
int main() {
cin>>n;
int lin=0;
for(int i=1;i<=n;i++){
cin>>lin;
a[lin]++;
}for(auto i=a.begin();i!=a.end();i++){
if(i->second!=0){
for(auto j=1;j<=i->second;j++){
cout<<i->first<<" ";
}
}
}
return 0;
}
归并排序:
归并排序是个啥?
(以下这段话由AI小助手生成)
归并排序是一种分治法,它的基本思想是将一个大数组分割成两个较小的子数组,然后递归地对每个子数组进行排序,最后再将这两个有序子数组合并为一个有序的大数组。归并排序的优点是稳定性好、时间复杂度低,但空间复杂度较高。
归并排序的步骤:
(以下这段话由AI小助手生成)
-
将待排序的数组分割成两个较小的子数组,其中一个包含元素a[0...n/2],另一个包含元素a[n/2+1...n]。
-
递归地对每个子数组进行排序,其中排序的方法是使用归并排序的思想:将子数组分割成更小的子数组,直到每个子数组只包含一个元素为止;然后再将这些子数组合并起来,形成一个新的有序数组。
-
最后将两个已排序的子数组合并为一个有序的大数组。这个过程是通过比较两个子数组中的元素大小,然后选择其中较小的一个元素添加到新的大数组中,重复此过程,直到所有的元素都被添加到新的大数组中。
(后面的话都是我自己说的)
前两部都很好理解,我来说说第三步。我们已经分成了两个长度相等或接近的有序的子序列,我们可以用两个变量表示两个子序列的第一个元素,之后进行比较,将小的放到新的数组里,这个变量++,以此类推,直到有一个放完,最后,在用while循环来处理剩下的数,最后再用for循环导到原来的数组里。
代码:
#include<iostream>
using namespace std;
int yuan[114514],xin[114514];
void merge_fix(int l,int r){
int mid=(l+r)/2;
int ll=l,lr=mid,rl=mid+1,rr=r;
int cnt=l-1;
while(ll<=lr&&rl<=rr){
if(yuan[ll]<yuan[rl]){
xin[++cnt]=yuan[ll++];
}else{
xin[++cnt]=yuan[rl++];
}
}while(rl<=rr)xin[++cnt]=yuan[rl++];
while(ll<=lr)xin[++cnt]=yuan[ll++];
for(int i=l;i<=r;i++)yuan[i]=xin[i];
}
void merge_sort(int l,int r){
if(l>=r)return;
int mid=(l+r)/2;
merge_sort(l,mid);
merge_sort(mid+1,r);
merge_fix(l,r);
return;
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>yuan[i];
}merge_sort(1,n);
for(int i=1;i<=n;i++){
cout<<yuan[i]<<" ";
}
return 0;
}
AC记录
彩蛋:
点个关注,点这里 查看彩蛋!