【跳出for循环嵌套】公鸡五文钱一只,母鸡三文钱一只,小鸡三只一文钱。问:用m文钱买m只鸡,公鸡、母鸡、小鸡各买多少只?并输出最小购买公鸡的数,并增加无解答案。

此题是百元买百鸡(C)的升级版

1.增加了用m文钱买m只鸡的要求,解决这个问题我们只需添加一个scanf函数即可。

2.输出最小可购买公鸡的数。

3.增加无解答案。

主要思路是用枚举法做,就是多个for循环嵌套,用if判断成立条件,暴力解方程式即可。思路很简单,这里有两个小问题。

一、最小公鸡数

由于多个for循环嵌套的步骤是外部执行一次,内部全部执行,而外部又从最小值开始自增。那么当条件方程式第一次成立时,最外部的自增元素一定是众多成立情况中最小的那一个。所以我们用最外层的自增元素去表示公鸡数就可以得出满足要求的最小公鸡数。求最小母鸡,小鸡也是同理。

那既然求出了最小公鸡数,就没有必要再次循环计算了,只需输出第一次方程式成立的值。那该如何跳出多个for循环呢?本文对此详细讨论。

二、跳出嵌套for循环的方法(主要内容)

1. 直接return 0; 函数结束程序。此方法只适用后面没有代码的情况,简单粗暴。

# include<stdio.h>
int main()
{
	int m, sum = 0;
	scanf_s("%d", &m);
	for (int i = 0; i <= m; ++i) //i表示公鸡数
	{
		for (int j = 0; j <= m; ++j)
		{
			for (int k = 0; k * 3 <= m; ++k)//把3只小鸡视为1捆,按捆去买,1捆就是三只小鸡,1分钱
			{
				if (i * 5 + j * 3 + k == m && i + j + k * 3 == m)//k是捆数
				{
				   printf("%d文钱可买最少的公鸡数为%d只,母鸡%d只,小鸡%d只\n", m, i, j, k * 3);
					return 0;//第一次输出后,结束程序。
				}
			}
		}
	}
}

 但题目要求我们输出无解答案,那就不能使用return 0;结束程序了。(或者用exit)

2.将for循环写入 bool函数

bool 含数可以返回真假, 当与if套用时,如果我们只规定一个返回值

bool函数默认返回 true

# include<stdio.h>
bool f(int m)
{
	if (m == 0)
		return false;
}
void main()
{
	int m;
	scanf_s("%d", &m); // 输入0 , 输出为false
	if (f(bool(m)))    // 输入除0以外的值 输出为 true
		printf("true");
	else
		printf("false");
}

所以:

我们用bool函数将for循环存入,只对数据进行处理,bool函数会帮我们返回真, 这样也跳出了for循环

bool f(int m)
{
	for (int i = 0; i <= m; ++i)
	{
		for (int j = 0; j <= m; ++j)
		{
			for (int k = 0; k * 3 <= m; ++k)
			{
				if (i * 5 + j * 3 + k == m && i + j + k * 3 == m && i < j && i < k * 3)
					return false;
			}
		}
	}
}
int main()
{
	int m;
	scanf_s("%d", &m);
	if (f(m))
		printf("No answer");
	else
	{
		for (int i = 0; i <= m; ++i)
		{
			for (int j = 0; j <= m; ++j)
			{
				for (int k = 0; k * 3 <= m; ++k)
				{
					if (i * 5 + j * 3 + k == m && i + j + k * 3 == m)
					{
						printf("%d %d %d", i, j, k * 3);
						return 0;
					}
				}
			}
		}
	}
}

3. 跳出外层的for循环 (推荐)

如果单独用break;的话,是不能结束整个for循环的

所以我们要引入一个判断变量flag,并结合if判断,如果满足条件,就题用break打断外部的for,这样内部就不会执行啦!

# include<stdio.h>
int main()
{
	int m, sum = 0, flag = 0;
	scanf_s("%d", &m);
	for (int i = 0; i <= m; ++i)
	{
        if (falg == 1) break; //只写这里也可以 需要break我也不知道多少次 也实现了不执行内部for的目的
		for (int j = 0; j <= m; ++j)
		{
			if (falg == 1) break; //只写这里也可以 需要break我也不知道多少次
			for (int k = 0; k * 3 <= m; ++k)
			{
				if (i * 5 + j * 3 + k == m && i + j + k * 3 == m && i < j && i < k * 3)
				{
					printf("%d文钱可买最少公鸡数为%d只,母鸡%d只,小鸡%d只\n", m, i, j, k * 3);
					flag = 1;
					break;
				}
			}
		}
	}
	if (flag == 0) //不满足条件则无解
		printf("No Answer");
	return 0;
}

也可以优化如下

#include <stdio.h>
int main()
{
    int m, flag = 0;
    scanf("%d", &m);
    for (int i = 0; i <= m / 5; i++) //减少循环次数
    {
        if (flag == 1)break; //跳出最外层for即可
        for (int j = 0; j <= m / 3; j++)
        {
            int k = m - i - j; //减少for循环
            if (k + j * 9 + i * 15 == m * 3)
            {
                printf("%d %d %d", i, j, k);
                flag = 1;
                break;
            }
        }
    }
    if (flag == 0)printf("No Answer");
    return 0;
}
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值