• C语言之练习题


    在这里插入图片描述

    欢迎来到我的世界

    希望这篇文章对你有所帮助,有不足的地方还请指正,大家一起学习交流 !


    前言

    这是暑假题目的收尾文章,我的暑假作业一共写了四篇文章,本篇文章有四篇编程题,我很喜欢四这个数字,感谢铁子们的支持,新的篇章即将来到。😎

    在这里插入图片描述


    编程题

    第一题:珠玑妙算


    地址:oj地址


    在这里插入图片描述

    解题思路:

    暴力求解:分别记录猜中的个数和伪猜中的个数存入数组相应位置。

    • 猜中的个数好记录,直接让颜色组合的数组与猜测的数组进行一一比较,如果相等,那猜中的个数++;
    • 伪猜中的个数进行两次遍历;第一次遍历颜色组合的数组,在让该数组中的元素都遍历一遍猜测数组元素,如果相等伪猜中个数++,注意:并将猜测数组该位置赋值为空格' ' 这是为了确定唯一性;

    注意:这里伪猜中的个数包含了猜中的个数,所以在存入数组的是(伪猜中的个数-猜中的个数)

    代码实现:

    int* masterMind(char* solution, char* guess, int* returnSize) {
        *returnSize = 2;//只用两个元素,分别记录猜中个数和伪猜中个数
        int* arr = (int*)malloc(sizeof(int) * (*returnSize));
        int i = 0;
    
        int sum = 0;//猜中的个数
        for (i = 0; i < 4; i++)
        {
            if (solution[i] == guess[i])
            {
                sum++;
            }
        }
        arr[0] = sum;
    
        int count = 0;//记录违猜中的个数
        int j = 0;
        for (i = 0; i < 4; i++)
        {
            for (j = 0; j < 4; j++)
            {
                if (solution[i] == guess[j] )//找到相等的,且将猜测数组中的值该成空格;
                {
                    count++;
                    guess[j] = ' ';
                    break;
                }
            }
        }
    
        arr[1] = count - arr[0];
        return arr;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    第二题:寻找奇数


    地址:oj地址


    在这里插入图片描述

    解题思路:

    这道题其实也叫做:寻找单身狗
    考察的是对按位异或^的深刻了解:

    我们首先来了解下^他的运算原则是:相同为0,相异位1;
    在来看到:一个数^他相同数结果为0
    假如一个数3:二进制码:011
    3 ^ 3 = 0 所以:3 ^ 0 = 3
    结论: 0 ^任何数都 = 该数本身,任何数^该数本身=0

    所以我们可以利用这一特性:
    题目中说输入一个数组,该数组只有唯一的一个单着的;
    所以让0按位异或^上该数组所有数就可以找出那个单着的数;
    就像单身狗一样,无所遁形😎

    代码实现:

    int main() {
        int n=0;
        scanf("%d",&n);
        int i=0;
        int arr=0;
        int m=0;//m^上该数组所有元素
        for(i=0;i<n;i++)
        {
            scanf("%d",&arr);
            m^=arr;
        }
    
        printf("%d",m);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    第三题:寻找峰值


    地址:oj地址


    在这里插入图片描述
    在这里插入图片描述

    第一个解题思路:暴力求解

    根据在数组范围内,只要一个数严格大于两侧的数就为峰值,对nums数组进行遍历,找到一个峰值即可;

    暴力求解,代码实现:

    int findPeakElement(int* nums, int numsLen ) {
        // write code here
        int i=0;
        if(numsLen==1)//若只有一个值,其本身就是峰值
            return 0;
     
        if(nums[0]>nums[1])//若峰值为第一个元素,单独讨论
            return 0;
        if(nums[numsLen-1]>nums[numsLen-2])//若峰值为最后一个元素,单独讨论
            return numsLen-1;
        for(i=1;i<numsLen-1;i++)//遍历[1,numsLen-1)范围
        {
            if(nums[i]>nums[i-1] && nums[i]>nums[i+1])//找到峰值
            {
                return i;
            }
        }
        return 0;//若还是找不到峰值,就返回0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    第二个解题思路:二分思想

    在首元素和最后一个为峰值都要单独考虑;
    二分思想:设置三个指针left,right,找到中间位置的值mid,然后根据mid和其两边的值的进行比较,哪边要大于mid值就往那边找峰值,直到mid值严格大于其两边的值;

    • 如果 nums[mid],那么意味这峰值位于mid右边,根据二分查找的思想,让left=mid+1
    • nums[mid]>=nums[mid+1],那就意味着峰值位于mid的左边;根据二分查找的思想,让right=mid;
    • 注意mid的值:mid = left + (right - left) / 2;

    -在这里插入图片描述

    二分求解,代码实现:

    int findPeakElement(int* nums, int numsLen ) {
        // write code here
        if (numsLen == 1 || nums[0] > nums[1]) return 0;
     
        if (nums[numsLen - 1] > nums[numsLen - 2]) return numsLen - 1;
        int left = 0, right = numsLen - 1, mid;
     
        while (left < right) {
            mid = left + (right - left) / 2;
            if (nums[mid] < nums[mid+1])//中间比右边小,意味着右边肯定有个峰值
                left = mid + 1;
            else //否则在左边包括当前位置肯定有个峰值
                right = mid;
        }
        return right;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    第四题:数对


    地址:oj地址


    在这里插入图片描述

    第一个解题思路:暴力求解

    暴力求解:将 x y 分别遍历 [1, n] ,进行判断当 x % y >= k 时统计计数 count++ 即可,但是这样的话当 n 的值非常大的时候循环次数将非常恐怖,需要循环 n^2 次;
    注意:这个方法会运行超时;

    代码实现:

    #include 
    
    int main() {
        int i=0;
        int j=0;
        int n,k;
        long count=0;
        scanf("%d%d",&n,&k);
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
            {
                if((i%j)>=2)
                {
                    count++;
                }
            }
        }
        printf("%ld",count);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    第二个解题思路:

    要理解数学公式:((n/y)*(y-k))+((n%y;
    假如n=10,k=3
    y <=k 时,意味着任何数字取模y的结果都在 [0, k-1]之间,都是不符合条件的。
    y=k+1=4,x 符合条件的数字有 3,7;
    y=k+2=5,x 符合条件的数字有 3,4,8,9;

    所以当y=k+n
    x小于y当前值,且符合条件的数字数量是:y-k个;
    x大于y当前值,小于2*y的数据中,且符合条件的数字数量是:y-k个;

    可以能看出来,在y的整数倍区间内,x符合条件的数量就是 (n / y) * (y - k)个;
    n / y 表示有多少个完整的 0 ~ y区间,y - k 表示有每个区间内有多少个符合条件的数字;
    最后还要考虑的是6...往后这种超出倍数区间超过n的部分的统计
    n % y 就是多出完整区间部分的数字个数,其中k以下的不用考虑,
    则符合条件的是 n % y - (k-1) 个。
    这里需要注意的是类似于9这种超出完整区间的数字个数 本就小于k的情况,则为0
    最终公式:(n / y) * (y - k) + ((n % y < k) ? 0, (n % y - k + 1));

    代码实现:

    #include 
    
    int main() {
        long n,k;
        scanf("%ld%ld",&n,&k);
        if(k==0)
        {
            printf("%ld",n*n);
            return 0;
        }
            
        long count=0;
        for(long y=k+1;y<=n;y++)
        {
            count+=((n/y)*(y-k))+((n%y<k)?0:(n%y-k+1));
        }
        printf("%ld",count);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    总结


    到了最后:感谢支持

    我还想告诉你的是:
    ------------对过程全力以赴,对结果淡然处之
    也是对我自己讲的

  • 相关阅读:
    2022前端笔试题总结
    ElementUI之登陆+注册
    《价值流动-Project To Product》读后感
    入门级制作电子期刊的网站推荐
    设计模式之美——封装,继承,多态的意义
    数据结构学习笔记 5-1 单调队列(Monotone-Queue)与 LeetCode真题(Java)
    跨境erp系统功能分析
    位图,布隆过滤器,哈希分割
    小学生的护眼灯哪个品牌最好?分享学生护眼台灯品牌
    世界前沿技术发展报告2023《世界航空技术发展报告》(二)军用飞机技术
  • 原文地址:https://blog.csdn.net/m0_66780695/article/details/132685274