11.7 算法和刷题

快速排列:

回顾一下曾经的冒泡算法:

#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;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值