• [HDOJ5584]LCM Walk(数论,规律)


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5584

    给一个坐标(ex, ey),问是由哪几个点走过来的。走的规则是x或者y加上他们的最小公倍数lcm(x, y)。

    考虑(ex, ey)是由其他点走过来的,不妨设当走到(x,y)时候,gcd(x, y)=k,x=k*m1, y=k*m2。

    下一步有可能是(x, y+x*y/gcd(x, y))或者是(x+x*y/gcd(x,y), y)。

    用k和m1,m2来表示为(k*m1, k*m2+m1*m2*k)=(k*m1, k*m2*(m1+1)), 或(k*m1+m1*m2*k, k*m2)=(k*m1*(m2+1), k*m2)。

    下面只关注(k*m1*(m2+1), k*m2)。m1和m2互质并且(m2+1)与m2也互质。

    那么gcd(k*m1*(m2+1), k*m2)=k,即无论如何变化,它们的最大公因数都是k。这也证明了路径唯一,我们求的是可能的起点位置数,所以直接考虑每次都是x来加的情况(即y>x的时候,交换x,y)。我们可以从(ex, ey)上逆推回去。x'=k1*m1/(m2+1),当x不是(y + k)的整数倍以后,即x/(k*(m2+1))不为0结束。

     1 #include <algorithm>
     2 #include <iostream>
     3 #include <iomanip>
     4 #include <cstring>
     5 #include <climits>
     6 #include <complex>
     7 #include <fstream>
     8 #include <cassert>
     9 #include <cstdio>
    10 #include <bitset>
    11 #include <vector>
    12 #include <deque>
    13 #include <queue>
    14 #include <stack>
    15 #include <ctime>
    16 #include <set>
    17 #include <map>
    18 #include <cmath>
    19 
    20 using namespace std;
    21 
    22 int ex, ey;
    23 
    24 int main() {
    25     // freopen("in", "r", stdin);
    26     int T, _ = 1;
    27     scanf("%d", &T);
    28     while(T--) {
    29         scanf("%d %d", &ex, &ey);
    30         int k = __gcd(ex, ey);
    31         if(ex < ey) swap(ex, ey);
    32         int ans = 1;
    33         while(1) {
    34             if(ex % (ey + k) != 0) break;
    35             ans++;
    36             ex = ex / (ey / k + 1);
    37             if(ex < ey) swap(ex, ey);
    38             k = __gcd(ex, ey);
    39         }
    40         printf("Case #%d: %d
    ", _++, ans);
    41     }
    42     return 0;
    43 }
  • 相关阅读:
    Python-asyncio
    Python-异步编程
    软件工程个人作业01
    《构建之法》阅读笔记6
    《构建之法》阅读笔记5
    《构建之法》阅读笔记4
    《构建之法》阅读笔记3
    《构建之法》第二章阅读笔记
    《构建之法》第一章阅读笔记
    开发web信息管理系统用到的相关技术
  • 原文地址:https://www.cnblogs.com/kirai/p/5427025.html
Copyright © 2020-2023  润新知