题目:
问题 D: [思维] 奇怪的减法
时间限制: 1 Sec 内存限制: 128 MB
提交: 327 解决: 42
[提交][状态][讨论版]
题目描述
你有两个变量a和b。 考虑使用这些变量执行的以下一系列操作:
1. 如果a = 0或b = 0,则结束该过程。 否则,转到步骤2;
2. 如果a≥2·b,则将a的值设置为 a - 2·b,并重复步骤1.否则,转到步骤3;
3. 如果b≥2·a,则将b的值设置为b - 2·a,并重复步骤1.否则,结束该过程。
最初,a和b的值是正整数,因此该过程将是有限的
求流程结束后a和b的值
输入
测试数据有多组
输入的唯一行包含两个整数n和m(1≤n,m≤2×109)。 n是变量a的初始值,m是变量b的初始值。
输出
对于每组测试数据
输出结束后a和b的值
样例输入
12 5
31 12
样例输出
0 1
7 12
代码块:
1.时间超限:
#include <stdio.h>
int main(void)
{
int a, b;
while(scanf("%d%d", &a, &b)!=EOF)
{
while((b>=2*a||a>=2*b)&&a>0&&b>0)
{
if(b>=2*a)
b = b-2*a;
else
a = a-2*b;
}
printf("%d %d\n", a, b);
}
return 0;
}
2.正确(待验证):
#include <stdio.h>
int main(void)
{
int a, b;
while(scanf("%d%d", &a, &b)!=EOF)
{
while((b>=2*a||a>=2*b)&&a>0&&b>0)
{
if(b>=2*a)
b = b%(2*a);
else
a = a%(2*b);
}
printf("%d %d\n", a, b);
}
return 0;
}
题解:
- 这里代码1超限的原因在于当a/b很大时,每次循环a只执行一次自减2b,要经过很多次循环后才能达到a/b<2。经过优化后a直接取对2b的余数,无论什么情况一次循环就够了。
- 所以对于这种多次循环重复同一种操作的情况,要想办法对操作进行改进,使得其尽量一步到位,尽量避免程序重复的操作。