CF946B Weird Subtraction Process 题解

Content

有两个数 \(a,b\),执行如下操作:

  1. 如果 \(a,b\) 中有一个数是 \(0\),结束操作,否则跳到操作 \(2\)。
  2. 如果 \(a\geqslant 2b\),那么 \(a\leftarrow a-2b\),并跳回操作 \(1\),否则跳到操作 \(3\)。
  3. 如果 \(b\geqslant 2a\),那么 \(b\leftarrow b-2a\),并跳回操作 \(1\),否则结束操作。

求出操作结束后的 \(a,b\)。

数据范围:\(1\leqslant a,b\leqslant 10^{18}\)。

Solution

那么我们发现,如果 \(a=10^{18},b=1\) 的极限数据下,直接模拟肯定会时间爆炸的,那么怎么办?我们发现,如果满足要求,那么一个数会一直减一直减,知道这个数不满足要求为止,那么不就是取模操作吗?那么上面的 \(2,3\) 操作换成 \(a\leftarrow a\mod 2b,b\leftarrow b\mod 2a\),不就可以节省很多时间吗?

剩下的就只是判断的问题了。

Code

long long a, b;

void ans(ll a, ll b) {
	if(!a || !b) {
		writell(a), putchar(' '), writell(b);
		return;
	}
	if(a >= 2 * b)	ans(a % (2 * b), b);
	else if(b >= 2 * a) 	ans(a, b % (2 * a));
	else {
		writell(a), putchar(' '), writell(b);
		return;
	}
}

int main() {
	getll(a), getll(b);
	ans(a, b);
	return 0;
}
上一篇:vue.config.js 配置记录


下一篇:Django中间件