C语言百日刷题第十一天

前言

今天是刷题第11天,放弃不难,但坚持一定很酷~

快来跟我一起刷题吧。

在这里插入图片描述

C语言百日刷题第十一天

  • 前言
  • 86.球能弹多高?
  • 87.对角线之和
  • 88.数字调序
  • 89.兔子繁殖
  • 90.原地删除指定元素

86.球能弹多高?

题目:一球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在第10次落地时,共经过多少米?第10次反弹多高?

C语言百日刷题第十一天_第1张图片

分析:唯一要注意的就是第十次落下的时候,需要减去高度。

#include
int main()
{
	float high = 100;
	float sum = 0;
	for (int i = 0; i < 10; i++)
	{
		sum = sum + high+high/2;
		high = high / 2;
	}
	sum = sum - high;
	printf("10次后的反弹高度为:%f \n落地高度共为:%f\n ", high, sum);
	return 0;
}

87.对角线之和

题目:打印一个3*3矩阵的主对角线的元素,并求主对角线元素之和。

分析:一看见3*3的矩阵,就应该想到二维数组。其次,主对角线的元素下标不就是两个下标相同的元素嘛?
所以可以很轻松的写出该程序的代码。

#include
int main()
{
	int a[3][3] = { 0 };
	int sum = 0;
	printf("请依次输入3*3矩阵的元素,从上至下,从左往右:\n");
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			scanf("%d", &a[i][j]);
			printf(" %d ", a[i][j]);
		}
		printf("\n");
	}
	printf("对角线元素为:");
	for (int i = 0; i < 3; i++)
	{
		printf(" %d ", a[i][i]);
		sum += a[i][i];
	}
	printf("\n");
	printf("主对角线之和为:%d\n", sum);
	return 0;
}

88.数字调序

题目:有n个整数,使前面各数顺序向后移m个位置,最后m个数变成前面m个数
例如:
输入:

10
2
1 2 3 4 5 6 7 8 9 10

输出:

9 10 1 2 3 4 5 6 7 8

方法一:循环

# include
int main()
{
	int m, n, ch[1000];
	scanf("%d", &n);
	scanf("%d", &m);
	for (int i = 0; i < n; i++)
	{
		scanf("%d", &ch[i]);
	}
	for (int i = n - 1; i >= 0; i--)
	{
		ch[i + m] = ch[i];
	}
	for (int j = 0; j < m; j++)
	{
		ch[j] = ch[n + j];
	}
	for (int i = 0; i < n; i++)
	{
		printf("%d ", ch[i]);
	}
	return 0;
}

方法二:指针 + 递归

#include
//写一个移动函数
int* move(int str[],int n,int m)
{
	int *p,str_end;
	if(m>0) 
	{
		str_end=*(str+n-1);
		for(p=str+n-1;p>str;p--)
			*p=*(p-1);    
		*p=str_end;
		m--;
	}
	if(m>0)
		move(str,n,m); //递归
	else
		return p;
}
//主函数调用
int main()
{
	int a[20],i,m,n;
	scanf("%d %d",&n,&m);
	for(i=0;i<n;i++)
		scanf("%d",&a[i]);
	move(a,n,m);
	for(i=0;i<n;i++)
		printf("%d ",a[i]);
	return 0; 
}

89.兔子繁殖

题目:有一对兔子,从出生后第 3 个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,两年内每个月的兔子总数为多少?
C语言百日刷题第十一天_第2张图片

分析:兔子的繁殖问题是一个非常经典的斐波拉契数列问题。
当然,我们要注意,这里题目问的是多少只,而不是多少对。

斐波拉契数列:
C语言百日刷题第十一天_第3张图片

递归写法:

#include
int fac(int num)
{
	if (num == 1 || num == 2)
		return 1;
	return fac(num - 1) + fac(num - 2);
}
int main()
{
	int n = 0;
	scanf("%d", &n);
	printf("%d个月共有%d只兔子\n", n, 2*fac(n));
	return 0;
}

和斐波拉契数列一样,递归写法虽然方便,但是当数值过大时,会进行多次的无意义重复运算。所以相比于递归,迭代的写法计算的更快。

迭代写法:

#include
int  fac(int x)
{
	int a = 1;
	int b = 1;
	int c = 1;
	while (x > 2)
	{
		c = a + b;
		b = a;
		a = c;
		x--;
	}
	return c;
}
int main()
{
	int n = 0;
	scanf("%d", &n);
	printf("%d个月共有%d只兔子\n", n, 2*fac(n));
	return 0;
}

90.原地删除指定元素

题目:给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。
例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。

方法一:暴力解法:双循环,一个for循环遍历数组元素 ,第二个for循环更新数组。

int removeElement(int* nums, int numsSize, int val){
    int size = numsSize;
    for (int i = 0; i < size; i++) 
        {
            if (nums[i] == val) 
            { 
                for (int j = i + 1; j < size; j++) {
                    nums[j - 1] = nums[j];
                }
                i--; 
                size--;
            }
        }
        return size;
}

方法二:双指针

int removeElement(int* nums, int numsSize, int val)
{
    int slow = 0;
    for(int fast = 0; fast < numsSize; fast++) 
    {
        if(nums[fast] != val) 
        {
            nums[slow++] = nums[fast];
        } 
    }
    return slow;
}

你可能感兴趣的:(#,C语言百日刷题,c语言,算法,基础题,C语言经典题)