变幻莫测
思路
拿到这道题先别急,想一下:两种操作——交换 (X, Y) -> (Y, X) 和变换 (X, Y) -> (X+Y, X-Y),要让 X 等于 Y,什么情况下做得到?
关键观察:变换操作 (X, Y) -> (X+Y, X-Y) 之后,新的两个数的乘积是 (X+Y)(X-Y) = X^2 - Y^2。如果 X != Y 且 X != -Y 且 XY != 0,那变换之后两个数都不为零,且绝对值也不相等。交换操作只是翻转顺序,不改变这个性质。
所以不管你怎么折腾,只要初始 X 和 Y 既不相等、也不互为相反数、也没有谁是零,那就永远凑不出 X = Y,直接输出 -1。
分情况讨论
那什么时候能凑出来呢?其实就四种情况:
- X == Y:已经相等了,0 步
- Y == 0:做一次变换 (X, 0) -> (X, X),1 步
- X == 0:先交换 (0, Y) -> (Y, 0),再变换 (Y, 0) -> (Y, Y),2 步
- X == -Y(且不为零):变换 (X, -X) -> (0, 2X),交换 (2X, 0),变换 (2X, 2X),3 步
其他所有情况都是 -1。
为什么其他情况不可能?
核心不变量:如果当前 X != 0 且 Y != 0 且 |X| != |Y|,那做变换后 X+Y != 0 且 X-Y != 0(因为 X != -Y 且 X != Y),而且 |X+Y| != |X-Y|(因为这等价于 XY = 0,矛盾)。交换不改变这些性质。所以这组状态是"封闭"的,永远走不到 X = Y。
代码
#include <iostream>
using namespace std;
int main() {
long long x, y;
cin >> x >> y;
if (x == y) {
cout << 0 << endl;
} else if (y == 0) {
cout << 1 << endl; // 变换一次搞定
} else if (x == 0) {
cout << 2 << endl; // 交换 + 变换
} else if (x == -y) {
cout << 3 << endl; // 变换 + 交换 + 变换
} else {
cout << -1 << endl; // 不可能
}
return 0;
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long x = sc.nextLong();
long y = sc.nextLong();
if (x == y) {
System.out.println(0);
} else if (y == 0) {
System.out.println(1); // 变换一次搞定
} else if (x == 0) {
System.out.println(2); // 交换 + 变换
} else if (x == -y) {
System.out.println(3); // 变换 + 交换 + 变换
} else {
System.out.println(-1); // 不可能
}
}
}
x, y = map(int, input().split())
if x == y:
print(0)
elif y == 0:
print(1)
elif x == 0:
print(2)
elif x == -y:
print(3)
else:
print(-1)
const readline = require('readline');
const rl = readline.createInterface({ input: process.stdin });
const lines = [];
rl.on('line', line => lines.push(line));
rl.on('close', () => {
const parts = lines[0].trim().split(' ');
const x = BigInt(parts[0]);
const y = BigInt(parts[1]);
if (x === y) {
console.log(0);
} else if (y === 0n) {
console.log(1);
} else if (x === 0n) {
console.log(2);
} else if (x === -y) {
console.log(3);
} else {
console.log(-1);
}
});
复杂度分析
- 时间复杂度:
,纯分类讨论,常数时间
- 空间复杂度:
,只用了两个变量
总结
这题看着像 BFS 搜索,但仔细想想会发现状态空间是无限的,硬搜肯定不行。真正的突破口是分析"什么时候不可能"——当 X 和 Y 都非零且不互为相反数时,变换操作只会让数越来越大,永远凑不出相等。剩下的情况就那么几种,手推一下操作序列就完事了。典型的"看起来复杂,想清楚后几行代码"的数学题。



京公网安备 11010502036488号