快速排列:
回顾一下曾经的冒泡算法:
#include <stdio.h>
int main()
{
int t=0;
int n;
int a[100];
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
for(int j=0;j<n-1;j++)
{
for(int k=0;k<n-1-j;k++)
{
if(a[k]>a[k+1])
{
t=a[k];
a[k]=a[k+1];
a[k+1]=t;
}
}
}
for(int h=0;h<n;h++)
{
printf("%d\t",a[h]);
}
return 0;
}
冒泡算法将数字当成泡泡,进行多多多多次的比较,这样虽然也能实现排序的需求,但运行效率不够高。
快速排列:这只是一种算法,一种数学思维;
我们可以理解升高的排序,我们可以以左边的第一个人为基准,更高的在他的右边,矮一些的在他的左边。这样子就可以写程序了,定义数列最右边的为temp(基准),右边先开始找(一定得是右边开始,可以记成以哪边为基准,就从哪边开始),找比temp小的数字,没有找到就左移动,找到就停止。左边则相反,找比temp大的数字,没有找到就右移动,找到就停止。当两边都停止时就进行数字交换。这时候,就像升高一样,已经以temp为基准分成了两队,在每一队里如此反复直到左边不能再向右边移动(left>light)。
#include <stdio.h>
int a[101],n;//定义全局变量,这两个变量需要在子函数中使用
void quicksort(int left, int right) {
int i, j, t, temp;
if(left > right)//当left>right时就结束函数
return;
temp = a[left]; //temp中存的就是基准数
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);//继续处理右边的 ,这里是一个递归的过程
}
int main() {
int i;
//读入数据
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]);
}
//printf("%d\n", a[n]);
return 0;
}
刷题:
1⃣️:
题目描述
某校大门外长度为 ll 的马路上有一排树,每两棵相邻的树之间的间隔都是 11 米。我们可以把马路看成一个数轴,马路的一端在数轴 00 的位置,另一端在 ll 的位置;数轴上的每个整数点,即 0,1,2,…,l0,1,2,…,l,都种有一棵树。
由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。
输入格式
第一行有两个整数,分别表示马路的长度 ll 和区域的数目 mm。
接下来 mm 行,每行两个整数 u,vu,v,表示一个区域的起始点和终止点的坐标。
输出格式
输出一行一个整数,表示将这些树都移走后,马路上剩余的树木数量。
输入输出样例
输入 #1复制
500 3 150 300 100 200 470 471输出 #1复制
298#include<stdio.h> int main() { int a[100000]={1}; int l,m; int sum=0; int j,k,t; scanf("%d%d",&l,&m); t=l; for(int i=0;i<=l;i++) { a[i]=1; } for(int i=0;i<m;i++) { scanf("%d%d",&j,&k); for(int q=j;q<=k;q++) { if(a[q]==1) { a[q]=0; } } } //for(int i=0;i<=l;i++) // { //printf("%d ",a[i]); // } for(int i=0;i<=l;i++) { sum+=a[i]; } printf("%d",sum); return 0; }
2⃣️:
题目描述
给出一个正整数 n(n≤100)n(n≤100),然后对这个数字一直进行下面的操作:如果这个数字是奇数,那么将其乘 3 再加 1,否则除以 2。经过若干次循环后,最终都会回到 1。经过验证很大的数字(7×10117×1011)都可以按照这样的方式比变成 1,所以被称为“冰雹猜想”。例如当 nn 是 20,变化的过程是 [20, 10, 5, 16, 8, 4, 2, 1]。
根据给定的数字,验证这个猜想,并从最后的 1 开始,倒序输出整个变化序列。
输入格式
无
输出格式
无
输入输出样例
输入 #1复制
20输出 #1复制
1 2 4 8 16 5 10 20#include<stdio.h> int main() { int a; int cnt=0; scanf("%d",&a); int b[1000]={a}; if(a==0) { printf("0"); return 0; } for(int i=0;a!=1;i++) { if(a%2==0) { a/=2; }else{ a=a*3+1; } b[i+1]=a; //printf("a=%d b[%d]=%d\n",a,i,b[i]); cnt++; } //printf("%d\n",cnt); for(;cnt>=0;cnt--) { printf("%d ",b[cnt]); } return 0; }