將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;
}
留言列表