题目描述
利用快速排序算法将读入的 N 个数从小到大排序后输出。
快速排序是信息学竞赛的必备算法之一。对于快速排序不是很了解的同学可以自行上网查询相关资料,掌握后独立完成。
输入格式
第 11 行为一个正整数 NN,第 22 行包含 NN 个空格隔开的正整数 ai,为你需要进行排序的数,数据保证了 Ai 不超过 10^9。
输出格式
将给定的 N 个数从小到大输出,数之间空格隔开,行末换行且无空格。
输入输出样例
输入 #1
5 4 2 4 5 1
输出 #1
1 2 4 4 5
说明/提示
对于 20% 的数据,有 N≤10^3;
对于 100% 的数据,有 N≤10^5。
#include<stdio.h>
void quicksort(int left,int right);
int a[100001],n;
int main()
{
int i,j;
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
quicksort(0,n-1);
for(i=0;i<n;i++)
printf("%d ",a[i]);
return 0;
}
void quicksort(int left,int right)
{
int i,j,t,temp;
if(left>right)
return;
temp=a[left];
i=left;
j=right;
while(i!=j)
{
while(a[j]>=temp&&i<j)
j--;
while(a[i]<=temp&&i<j)
i++;
if(i<j)
{
t=a[i];
a[i]=a[j];
a[j]=t;
}
}
a[left]=a[i];
a[i]=temp;
quicksort(left,i-1);
quicksort(i+1,right);
return;
}
会出现超时,开启O2优化可以通过,但也可以采取优化或者直接用qsort,下面有一点演示
这里将基准数从默认左边改成了从中间选,平均时间变短。
#include <stdio.h>
#define maxn 100100
int a[maxn],n;
void qsort(int left,int right){
int i=left,j=right,mid=a[(left+right)/2],t;
while(i<=j){
while(a[i]<mid)i++;
while(mid<a[j])j--;
if(i<=j){
t=a[i],a[i]=a[j],a[j]=t,i++,j--;
}
}
if(left<j)qsort(left,j);
if(i<right)qsort(i,right);
}
int main(){
int i;
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%d",&a[i]);
qsort(1,n);
for(i=1;i<=n;i++)printf("%d ",a[i]);
return 0;
}
基准不再是默认最左边,而是取中间作为基准,平均用时短。
如果直接用qsort函数则如下
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n,i;
scanf("%d",&n);
int a[n];
for(i=0;i<n;i++)
scanf("%d",&a[i]);
int cmp(const void *a,const void *b)
{
return *(int *)a- *(int *)b;
}
qsort(a,n,sizeof(a[0]),cmp);
for(i=0;i<n;i++)
{
printf("%d ",a[i]);
}
return 0;
}
有一个别的问题,几乎所有的C语言教材上都说C语言函数可以嵌套调用,但不可以嵌套定义。实际上,函数能否嵌套定义与编译器有关,在GCC编译器下嵌套定义没问题,可以正常运行,在code blocks 和 Dev C++两个IDE(两者都用GCC)都可以正常运行。
实践一下
题目背景
HKE考完GDOI之后跟他的神犇小伙伴们一起去爬山。
题目描述
他在地形图上标记了N个点,每个点Pi都有一个坐标(xi,yi,zi)。所有点对中,高度值z不会相等。HKE准备从最低的点爬到最高的点,他的攀爬满足以下条件:
(1) 经过他标记的每一个点;
(2) 从第二个点开始,他经过的每一个点高度zz都比上一个点高;
(3) HKE会飞,他从一个点Pi爬到Pj的距离为两个点的欧几里得距离。即sqrt(Xi−Xj)2+(Yi−Yj)2+(Zi−Zj)2}
现在,HKE希望你能求出他攀爬的总距离。
输入格式
第一行,一个整数NN表示地图上的点数。
接下来N行,三个整数xi,yi,zi表示第i个点的坐标。
输出格式
一个实数,表示HKE需要攀爬的总距离(保留三位小数)
输入输出样例
输入 #1
5 2 2 2 1 1 1 4 4 4 3 3 3 5 5 5
输出 #1
6.928
说明/提示
对于100%的数据,1≤N≤50000,答案的范围在double范围内。
#include<stdio.h>
#include<math.h>
struct pi
{
double x;
double y;
double z;
}p[50000],t;
void qsort(int left,int right){
int i=left,j=right,mid=p[(left+right)/2].z;
while(i<=j){
while(p[i].z<mid)i++;
while(mid<p[j].z)j--;
if(i<=j){
t=p[i];
p[i]=p[j];
p[j]=t;
i++;
j--;
}
}
if(left<j)qsort(left,j);
if(i<right)qsort(i,right);
}
int main()
{
int n;
double s=0;
scanf("%d",&n);
int i,j;
for(i=0;i<n;i++)
scanf("%lf %lf %lf",&p[i].x,&p[i].y,&p[i].z);
qsort(0,n-1);
for(i=0;i<n-1;i++)
s+=sqrt(pow(p[i].x-p[i+1].x,2)+pow(p[i].y-p[i+1].y,2)+pow(p[i].z-p[i+1].z,2));
printf("%.3f",s);
return 0;
}
之后学习了队列,有一个理解的代码
题目:有一串数字被加密过,解密方法是每次取前两个数,删除第一个并把第二个放在最后,重复直到剩一个数字,将这个数也删除,删除的顺序就是解密后的答案
#include<stdio.h>
struct qu
{
int date[100];
int he;
int en;
}a;
int main()
{
int i;
a.he=1;
a.en=1;
for(i=1;i<=9;i++)
{
scanf("%d",&a.date[a.en]);
a.en++;
}
while(a.he<a.en)
{
printf("%d ",a.date[a.he]);
a.he ++;
a.date[a.en]=a.date[a.he];
a.he ++;
a.en ++;
}
return 0;
}