將N不斷的二分直到 N/2 < M

並將片數分成偶數和奇數  (其中 奇數 和 偶數 相鄰    <=>  | 奇數 - 偶數 | = 1)

 

計算規則如下

若 N/2 為偶數 => 偶數(新) = 2*偶數(舊) + 奇數  , 奇數不變

若 N/2 為奇數 => 偶數(新) = 奇數 , 奇數 = 2*偶數(舊) + 奇數

 

offset

將N"刻意"調整為偶數

-1:  N目前為較大的偶數

 1:  N目前為較小的偶數

 

 

 

#include <iostream>

using namespace std;

int main()
{
    unsigned long long int N, M, tmpN, tmpM;
    unsigned long long int odd, even, tmp, offset;

    while(cin >> N >> M)
    {
        tmpN = N, tmpM = M;

        if(N < M)
        {
            cout << "0\n";
            continue;
        }
        if(M == 1)
        {
            cout << N << endl;
            continue;
        }

        if(N%2 == 0)
        {
            even = 1;
            odd = 0;
        }
        else
        {
            even = 0;
            odd = 1;
            N++;
        }

        offset = -1;
        while(N/2 >= M)
        {
            N/=2;

            if( N%2 == 0)
                even = 2*even + odd;
            else
            {
                tmp = odd;
                odd += even*2;
                even = tmp;
                 N += offset;
                offset *= -1;
            }
        }
        //N較大
        if(offset == -1 && N == M)
            cout << even << endl;
        else if(offset == 1 && N < M)
            cout << odd << endl;
        else
            cout << even + odd << endl;
    }

    return 0;
}

 
arrow
arrow
    全站熱搜

    大神(偽) 發表在 痞客邦 留言(0) 人氣()