W

来源:互联网 发布:雷蛇游戏优化器 编辑:程序博客网 时间:2024/04/28 05:10

Friend number are defined recursively as follows.
(1) numbers 1 and 2 are friend number;
(2) if a and b are friend numbers, so is ab+a+b;
(3) only the numbers defined in (1) and (2) are friend number.
Now your task is to judge whether an integer is a friend number.

Input
There are several lines in input, each line has a nunnegative integer a, 0<=a<=2^30.
Output
For the number a on each line of the input, if a is a friend number, output “YES!”, otherwise output “NO!”.
Sample Input
31312112131
Sample Output
YES!YES!NO!



解题思路:


这道题其实就是一道数学题。。。。。。一开始有想过把全部可能的情况都打出来然后对应下标输出,但是我感觉这道题并不简单。


首先,a和b并不一定是不相同的



然后每次生成了新的friend数都要和之前的进行组合,在操作上我并没有想出非常好的办法。。。。。。


然后我尝试从别的角度思考。在我看来,这些这么强烈“数学味道”的题目,都可能要我们分析出其中的一些奥妙。


设c是一个friend数,然后c+a*b+a+b 其中a和b都是friend数

让我们做一下变形(两边都加1)

有可能有很多同学和我一样一开始觉得莫名其妙,为什么要这样子处理呢。。。。。。其实我就是观察a*b+a+b这个式子,首先它有a*b这个交叉项,然后有三项,也就是说我们可以大胆的猜测,应该有一个类似(a+x)(b+x)这样子的式子,所以我就猜想了一下可以两边都加一个1,这样子保证了a、b这两项系数不变。

如果想到了这里,那么我们其实已经解决了这个问题的绝大部分了。

首先我们可以根据这个式子

c+1=(a+1)*(b+1)

递推一下,首先,a、b、c都是friend数,也就是说,这个式子是可以不断延伸的,直到根源。

根源是什么,我们的一开始题目给的1、2两个friend数

也就是说c+1=2的n次方与3的m次方相乘

其中n和m都是大于等于0的正整数。


代码展示:

#include<iostream>
using namespace std;
int main()
{
    int n=0;
    int m=0;
    while(cin>>m)
    {
        if(m==0)
        {
            cout<<"NO!"<<endl;
            continue;
        }
        n=m+1;
        while(n%2==0)
        n=n/2;
        while(n%3==0)
        n=n/3;
        if(n==1)
        cout<<"YES!"<<endl;
        else
        cout<<"NO!"<<endl;
    }
}



首先有几点说明:


1、int可以满足2的30次方,所以我选了int类型。

2、当输入的数字是0的时候,需要进行特殊处理,要不然根据一开始的程序会输出YES!然后注意是continue不是break!你后面还要输入数字呢!-3-

嗯嗯,大概就是这么多啦~欢迎大家一起来讨论~

原创粉丝点击