链接:https://www.nowcoder.com/acm/contest/190/E
来源:牛客网
 

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述

Applese有个神奇的能力,TA可以把m个硬币融合成1个硬币,是不是很厉害。现在Applese有n个硬币,TA想把这个n个硬币融合成1个,请问他能完成吗?

输入描述

输入两个整数n,m(1 ≤ n, m ≤ 109)

输出描述

如果Applese能完成,输出"Yes",否则输出"No"。

 

样例输入

10 7

样例输出

No

解题思路

首先我们可以知道当m=1时,只有n=1的时候才可以。

当m!=1时我们有两种方法可以做。

法1:融合硬币的过程就是n / m的过程,而那些不足以融合的就是n % m,而把两者加在一起一直模拟这个过程,直到n < m为止,最后判断n是否为1就行了。

代码:

#include <iostream>
using namespace std;
int main()
{
    long long n, m;
    while (cin >> n >> m)
    {
    	if (m == 1)
    	{
            if (n == 1)
                puts("Yes");
            else puts("No");
        }
        else
        {
            while (n >= m)
                n = n / m + n % m;
            if (n == 1)
                puts("Yes");
            else puts("No");
        }
    }
    return 0;
}

法2:

我们可以假设当满足条件时共需n + a个(a为缺的),首先我们先从a个中取1个,从n个中取m-1个,可以融合成1个。然后再从n-m+1中取m-1个,用上次融合而成的1个再次融合成1个,一直这样下去,直到最终融合成一个。我们可以发现只要n % (m - 1) == 1就可以了,这个1为一开始从a中取的。

我们也可以这样理解:首先我们先从n个中取m-1个,再借1个,就可以融合成1个,然后把借的还了。一直这样借了再还下去,直到最终融合成1个,最后这个就不用还了。所以只要借最后一个就行了,即n % (m - 1) == 1就可以了,这个1为最后借的。

提示:n % (m - 1) == 1 等于 (n - 1) % (m - 1) == 0

代码:

#include <iostream>
using namespace std;
int main()
{
    long long n, m;
    while (cin >> n >> m)
    {
    	if (m + n == 2 || m != 1 && !((n - 1) % (m - 1)))
            puts("Yes");
        else puts("No");
    }
    return 0;
}