【C语言新手村】刷副本

🏝️专栏:【C语言新手村】

🌅主页:f狐o狸x


目录

一、 喝汽水问题

        1.1 分析问题

        1.2 题解代码

        1.3 另解

二、 调整数组使奇数全部都位于偶数前面

        2.1 分析问题

        2.2 题解代码

        2.3 另解

三、 有序序列合并

        3.1 分析问题

        3.2 题解代码

        3.3 另解

四、 有序序列判断

        4.1 分析问题

        4.2 题解代码

        4.3 优化代码


        学习过程中,我们需要不断练习一些题目来提高我们的水平,而一道题目的解法也不止有一种,在C语言中,我们除了要会写这道编程题,更要精益求精,尽量把自己的代码写到最好,这样才能提升我们写代码的能力

        更重要的是我们需要想出这道题如何解他,剩下的就是打代码

一、 喝汽水问题

        喝汽水,1瓶汽水1元,2个空瓶可以换一瓶汽水,给20元,可以喝多少汽水(编程实现)。

        1.1 分析问题

        20元——>可以和20瓶汽水——>有20个空瓶子——>换了10瓶汽水喝完——>10个空瓶——>换5瓶汽水……(如下图)

        现在我们试着用代码实现它

        1.2 题解代码

        


int main()
{
	//输入钱
	int money = 0;
	scanf("%d", &money);
	//计算
	int sum = money;
	int bottle = money;
	while (bottle >= 2)
	{
		sum += bottle / 2;
		bottle = bottle / 2 + bottle % 2;
	}
	//打印总共喝的饮料
	printf("%d", sum);
	return 0;
}

        1.3 另解

        多把上面的代码运算几次我们就可以发现,其实不管我们有多少钱(n元),最后我们都可以喝到(n-1)瓶汽水,所以这个代码还能优化

int main()
{
	//输入钱
	int money = 0;
	scanf("%d", &money);
	//计算
	int sum = 2 * money - 1;
	//打印总共喝的饮料
	printf("%d", sum);
	return 0;
}

二、 调整数组使奇数全部都位于偶数前面

        2.1 分析问题

        这题的概关键在于找出奇偶数,并把他们分开,第一种方法是运用和冒泡排序法一样的思路,如果是偶数,就把这个数字放到后面,最后就可以保证这个数组前面全是奇数,后面全是偶数

        2.2 题解代码

int main()
{
	int i = 0;
	int arr[10] = { 0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	//输入数组
	for (i = 0; i < sz; i++)
	{
		scanf("%d", &arr[i]);
	}
	//调整数组
	int j = 0;
	for (i = 0; i < sz - 1; i++)
	{
		for (j = 0; j < sz - 1 - i; j++)
		{
			if (arr[j] % 2 == 0)//判断arr[j]是否为偶数
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
	//打印数组
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

        2.3 另解

        我们也可以用两个指针,一个从左向右开始找偶数,一个从右向左找奇数,找到之后,他两交换,直到左边的指针大于等于右边的指针就停止

int main()
{
	int arr[10] = { 0 };
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	//输入
	for (i = 0; i < sz; i++)
	{
		scanf("%d", &arr[i]);
	}
	//调整
	int left = 0;
	int right = sz - 1;
	while (left < right)
	{
		while (arr[left] % 2 != 0)
		{
			left++;
		}
		while (arr[right] % 2 == 0)
		{
			right--;
		}
		if (left < right)
		{
			int tmp = arr[left];
			arr[left] = arr[right];
			arr[right] = tmp;
		}
	}
	//打印
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0; 
}

三、 有序序列合并

        输入两个升序排列的序列,将两个序列合并为一个有序序列并输出

        3.1 分析问题

        此题可以简单粗暴的直接把两个数组合并,再用冒泡排序搞定问题

        3.2 题解代码


int main()
{
	int m = 0;
	int n = 0;
	//输入两个有序数组
	scanf("%d %d", &n, &m);
	int arr1[20] = { 0 };
	int arr2[20] = { 0 };
	int arr3[40] = { 0 };
	int i = 0;
	for (i = 0; i < n; i++)
	{
		scanf("%d", &arr1[i]);
	}
	for (i = 0; i < m; i++)
	{
		scanf("%d", &arr2[i]);
	}
	//合并
	for (i = 0; i < n; i++)
	{
		arr3[i] = arr1[i];
	}
	for (i = n; i < m + n; i++)
	{
		arr3[i] = arr2[i - n];
	}
	for (i = 0; i < m + n - 1; i++)//冒泡排序
	{
		int j = 0;
		for (j = 0; j < m + n - 1 - i; j++)
		{
			if (arr3[j] > arr3[j + 1])
			{
				int tmp = arr3[j];
				arr3[j] = arr3[j + 1];
				arr3[j + 1] = tmp;
			}
		}
	}
	//打印
	for (i = 0; i < n + m; i++)
	{
		printf("%d ", arr3[i]);
	}
	return 0;
}

        3.3 另解

        上面那个方法用了太多次循环来解决问题,不是最优解,我们还是可以运用指针,因为都是有序数组,所以我们就将两个指针分别指向两个指针的第一个数字,谁小就先放谁,然后对应的指针加一,再次和将两个指向的数字相比较,直到其中一个数组中的数字被放完之后,再把剩下那个数组中的数字放进去就行了

        代码如下:

int main()
{
	int m = 0;
	int n = 0;
	//输入两个有序数组
	scanf("%d %d", &n, &m);
	int arr1[20] = { 0 };
	int arr2[20] = { 0 };
	int arr3[40] = { 0 };
	int i = 0;
	for (i = 0; i < n; i++)
	{
		scanf("%d", &arr1[i]);
	}
	for (i = 0; i < m; i++)
	{
		scanf("%d", &arr2[i]);
	}
	//合并
	i = 0;//指向arr1
	int j = 0;//指向arr2
	int k = 0;//指向arr3
	while (i != n && j != m)
	{
		if (arr1[i] < arr2[j])
		{
			arr3[k] = arr1[i];
			k++;
			i++;
		}
		else
		{
			arr3[k] = arr2[j];
			k++;
			j++;
		}
	}
	if (i == n)
	{
		while (j != m)
		{
			arr3[k] = arr2[j];
			k++;
			j++;
		}
	}
	else
	{
		while (i !=n)
		{
			arr3[k] = arr1[i];
			k++;
			i++;
		}
	}
	//打印
	for (i = 0; i < m + n; i++)
	{
		printf("%d ", arr3[i]);
	}
	return 0;
}

四、 有序序列判断

        输入一个整数序列,判断是否是有序序列,有序,指序列中的整数从小到大排序或者从大到小排序(相同元素也视为有序)。

        4.1 分析问题

        有序序列分为两类:1. 升序  2. 降序。因此我们可以从这里下手,如果不考虑相等的情况的话,我们可以先将数组中的第一个数字和第二个数字相比较,若打一个大于第二个则为降序判断,若第二个大于第一个则为升序判断。再来进行接下来的判断就行了(升序中只要有后一个数字小于前一个数字则为无序,同理,降序中只要后一个数字大于前一个数字则为无序)

        4.2 题解代码

int main()
{
    int n = 0;
    int i = 0;
    int arr[100] = { 0 };
    int flag = 1;
    //输入
    scanf("%d", &n);
    for (i = 0; i < n; i++)
    {
        scanf("%d", &arr[i]);
    }
    //判断
    i = 0;

        if (arr[i] > arr[i + 1])
        {
            for (i = 1; i < n - 1; i++)
            {
                if (arr[i] < arr[i + 1])
                {
                    printf("unsorted\n");
                    flag = 0;
                    break;
                }
            }
        }
        else if (arr[i] < arr[i + 1])
        {
            for (i = 1; i < n - 1; i++)
            {
                if (arr[i] > arr[i + 1])
                {
                    printf("unsorted\n");
                    flag = 0;
                    break;
                }
            }
        }

    //输出
    if (1 == flag)
        printf("sorted");
    return 0;
}

        不考虑有数字相等的情况,这样是没问题的,但是只要考虑了,代码就出bug了

        4.3 优化代码

        有bug就修复呗,这里我们将两个数相等的情况考虑进去,从左向右找除了“=”的其他符号“<”或“>”如果是“=”那就接着下一个找,这里用goto语句可以完美解决~(我真是天才)

int main()
{
    int n = 0;
    int i = 0;
    int arr[100] = { 0 };
    int flag = 1;
    //输入
    scanf("%d", &n);
    for (i = 0; i < n; i++)
    {
        scanf("%d", &arr[i]);
    }
    //判断
    i = 0;
    again:
        if (arr[i] > arr[i + 1])
        {
            for (i = 1; i < n - 1; i++)
            {
                if (arr[i] < arr[i + 1])
                {
                    printf("unsorted\n");
                    flag = 0;
                    break;
                }
            }
        }
        else if (arr[i] < arr[i + 1])
        {
            for (i = 1; i < n - 1; i++)
            {
                if (arr[i] > arr[i + 1])
                {
                    printf("unsorted\n");
                    flag = 0;
                    break;
                }
            }
        }
        else
        {
            i++;
            goto again;
        }

    //输出
    if (1 == flag)
        printf("sorted");
    return 0;
}

        如果大家有发现这个代码还是有bug的话欢迎在评论区讨论,只有不断地纠错改错才能使我们的水平越来越高!

        都看到这里了,要你们点个小赞不过分吧QAQ,顺便评论一下呗(求求啦)

        三连的帅哥美女必暴富~

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值