好题目啊!!!!! 模拟加剪枝!!!!! 题目大意: 时间限制: 0.50 sec 空间限制: 4096 KB 现在你有两个盒子,第一个盒子中有A个小球,第二个中有B个小球。(0 < A + B < 2147483648)。小球可以从一个盒子被拿到另一个盒子,但是每次从一个盒子拿到另一个盒子的小球的数量必须等于另一个盒子中小球的数量。你需要弄清是否能在若干次操作后将所有的小球移到同一个盒子。 输入 第一行包含用空格隔开的A和B 。 输出 如果不行的话,输出-1。否则输出最少需要移动多少次。 样例输入 2 6 样例输出 2 要想到最大公约数, 两个盒子的球的总和必须是偶数, 还有就是如果两个盒子的球不是相等的,那么他们的和的一半不能是奇数。 #include <iostream> #include <set> using namespace std; int gcd(int x, int y) { for(int t; t = x%y; x = y, y = t); return y; } int main() { int n, m; set<int> se; cin >> n >> m; se.clear(); if(n == 0 || m == 0) { cout << 0 << endl; return 0; } if(n == m) { cout << 1 << endl; return 0; } int x = gcd(n, m); n /= x; m /= x; int res = 0; if((n+m) % 2 == 1) { cout << -1 << endl; return 0; } if(((n+m)/2) % 2 == 1) { cout << -1 << endl; return 0; } if(m > n) swap(m, n); se.insert(n); while(1) { m += m; n = n - m / 2; res++; if(n == m) { cout << res+1 << endl; return 0; } if(m > n) swap(n, m); x = gcd(n, m); n /= x; m /= x; if((n+m) % 2 == 1) { cout << -1 << endl; return 0; } if(((n+m)/2) % 2 == 1) { cout << -1 << endl; return 0; } if(se.find(n) != se.end()) break; se.insert(n); } cout << -1 << endl; return 0; }