题目是CP1201
第一次代码是
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a=0,m,n,i;
scanf("%d,%d",&m,&n);
if((m+1)%i==0&&(n+1)%i==0&&i<m+1&&i<n+1)
{
a=i;
}
printf("%d\n",a);
return 0;
}
我以为能把符合那四个条件的数赋给变量a,但事实是if意味着只有系统随机给i生成的数满足那四个条件时才会把值赋给a,所以这么写是不对的。
应改为
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a=0,m,n,i;
scanf("%d%d",&m,&n);
do
{
if(m<=-1||n<=-1)
{
printf("Please input again.");
scanf("%d,%d",&m,&n);//对变量m和n重新读入数据的方式就是再把读入语句写一遍,用新数据覆盖老数据。
}
}
while(m<=-1||n<=-1);
m+=1;
n+=1;
int min=(m<n)?m:n;
for(i=1;i<=min; i++)
{
if(m%i==0&&n%i==0)
{
a=i;
}
}
printf("%d\n",a);
return 0;
}
其中增加了一个对输入的数据必须是正整数的限制,这种限制方法还可以这样
- 如果只判断一次
#include <stdio.h>
int main()
{
int m, n;
printf("请输入m和n的值:");
if (scanf("%d %d", &m, &n) != 2 || m <= 0 || n <= 0)
{
printf("输入的m和n必须是正整数!\n");
}
else
{
printf("输入的m和n分别是:%d 和 %d\n", m, n);
}
return 0;
}
若判断多次知道输入的类型正确为止,要用循环,因为如果仅仅在if语句后的printf("输入的m和n必须是正整数!\n");
后加一个scanf("%d %d", &m, &n);
,同样只能重输一次,所以要用循环。如下:
#include <stdio.h>
int main() {
int m, n;
do {
printf("请输入m和n的值:");
if (scanf("%d %d", &m, &n) != 2 || m <= 0 || n <= 0) {
printf("输入的m和n必须是正整数!\n");
} else {
printf("输入的m和n分别是:%d 和 %d\n", m, n);
break; // 输入符合要求时退出循环
}
} while (1); // 一直循环直至输入符合要求
return 0;
}
要实现当输入的m和n不符合要求时就继续输入直至符合要求为止,你可以使用一个循环来实现这个功能。可以使用do-while循环,这样可以先执行一次输入和判断,然后根据判断结果决定是否继续循环。在这个修改后的代码中,使用了do-while循环来实现当输入的m和n不符合要求时就继续输入直至符合要求为止。
在C语言中,while循环的条件部分需要是一个表达式,只有在表达式的值为真(非零)时才会执行循环体。因此,通常我们会使用一个逻辑表达式作为while循环的条件,例如i < 10或者x != 0等等。
在我之前给出的代码中,我使用了while(1)来表示一个无限循环。这是因为条件部分需要一个逻辑表达式,而1在C语言中被视为真。因此,while(1)表示条件永远为真,因此循环会一直执行下去,直到遇到break语句或者其他方式退出循环。
所以,在这个例子中,while(1)的作用是创建一个无限循环,直到输入的m和n符合要求时才会通过break语句退出循环。
求最大公约数时除了上面的正确代码,还可以把for循环处改为
for(i=min;i>=1; i--)
{
if(m%i==0&&n%i==0)
{
a=i;
break;
}
}
如果求最小公约数,可改为
for(i=min;i>=1; i--)
{
if(m%i0&&n%i0)
{
a=i;
}
}
或
for(i=1;i<=min; i++)
{
if(m%i0&&n%i0)
{
a=i;
break;
}
}
如果想求除了1以外的最小公约数,把两种代码里for后的括号里关系表达式里的等号去掉就行了。
且娄老师讲过求两个正整数的最大公约数可以用辗转相除法。
> 辗转相除法, 又名欧几里德算法(Euclidean algorithm),是求两个正整数之最大公约数的算法。它是已知最古老的算法, 其可追溯至公元前300年前。
> 它的具体做法是:用较大数除以较小数,再用出现的余数(第一余数)去除除数,再用出现的余数(第二余数)去除第一余数,如此反复,直到最后余数是0为止。如果是求两个数的最大公约数,那么最后的除数就是这两个数的最大公约数。
> 另一种求两数的最大公约数的方法是更相减损法。
> 例如:a=25,b=15,a%b=10,b%10=5,10%5=0,最后一个为被除数余数的除数就是5,5就是所求最大公约数。
> 自然语言描述
用辗转相除法确定两个正整数 a 和 b(a≥b) 的最大公因数gcd(a,b):
> 当a mod b=0 时gcd(a,b)=b,否则
gcd(a,b) = gcd(b,a mod b)
递归或循环运算得出结果
> 伪代码
这个算法可以用递归写成如下:
gcd 简易函数
c语言辗转相除代码:
C++语言实现
int gcd(int a, int b)
{
if(b==0) return a;
return gcd(b,a%b);
}
> C语言实现
int gcd(int a,int b)
{
return a%b?gcd(b,a%b):b;
}
所以这道题还可以用辗转相除法做。
标签:gcd,遇到,int,代码,最大公约数,问题,while,循环,余数
From: https://www.cnblogs.com/jfxyh061028/p/17884461.html