题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5584
题意:(x, y)经过一次操作可以变成(x+z, y)或(x, y+z)现在给你个点(ex, ey)输出有多少种可能的起点,这些起点经过若干次操作能变成(ex, ey)。
思路:我们考虑其中的一次变换,现在为(x, y)(y > x)那么它显然是由(x, y - z)变换来的。其中z = lcm(x, y - z),lcm(x, y - z) = x*(y-z)/gcd(x, y - z)。
这时如果你能发现规律gcd(x, y - z) = gcd(x, y)就可以轻松解决(不过要记得反过来验证下)。
如果没有发现以下规律也可以枚举gcd(x, y - z)的值(笨办法!!!)。
code:
1 #include <iostream> 2 using namespace std; 3 4 int gcd(int x, int y) 5 { 6 return !y ? x : gcd(y, x % y); 7 } 8 9 int main() 10 { 11 int T, cnt = 0; 12 cin >> T; 13 while (T--) { 14 int ex, ey; 15 cin >> ex >> ey; 16 int ans = 1; 17 while (ex >= 1 && ey >= 1 && ex != ey) { 18 if (ex < ey) swap(ex, ey); 19 int d = gcd(ex, ey); 20 int td = ey/d + 1; 21 if (0 == (ex % td) && gcd(ey, ex/td) == d) { 22 ++ans; 23 ex /= td; 24 } 25 else break; 26 } 27 cout << "Case #" << ++cnt << ": " << ans << endl; 28 } 29 return 0; 30 }