Less Coin Tosses(Gym - 102346L)【打表+找規律】

L - Less Coin Tosses Gym - 102346L

題目連接c++

算法

打表+找規律算法

時間複雜度O(logN)less

1.題意說的是給定你n位的二進制串,除了成對的(就是指那些1的個數相同或0的個數相同的),那些不成對的數有幾個。好比n爲3時,能夠有000,001,010,011,100,101,110,111這八種二進制數,其中001能夠與010配對,011能夠與110配對,剩餘的沒法再配對,因此最後輸出4。spa

2.看要求的數的範圍2<=N<=10^18,很是大,因此說不可能暴力去作,必定存在某種規律。code

3.既然成對的就是指二進制串中1的個數相同,那麼咱們能夠用組合數的知識來解決。即從n位數中挑m位爲1,看這樣的數有幾個,若爲偶數,則說明沒有不成對的,不然說明有落單的,這時加1便可。總結得出下列公式:blog

\[\displaystyle \sum_{i=0}^n (C_{n}^{i}\%2) \]

4.公式有了,問題來了,n這麼大怎麼算。對於這種題,很大可能性說明存在某種規律,如何找到規律,就須要打表實現。能夠根據下列代碼來打表。ci

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
/*打表*/
const int N = 1000;
ll c[N][N];
int n;
ll res[N];
void init()
{
    for(int i = 0; i < N;i ++)
        for(int j = 0; j <= i; j++)
        {
            if(!j) c[i][j] = 1;
            else
                c[i][j] = (c[i-1][j] + c[i-1][j-1]);
        }
}
int main()
{
    init();
    for(int i = 2; i < N; i++)
    {
        for(int j = 0; j <= i; j++)
        {
            res[i] += (c[i][j] % 2);
        }
        cout << "res[" << i << "] = " << res[i] << endl;
    }
}

因爲沒有取餘致使後面的數溢出變成負數了,不過沒有關係,咱們只須要看前面幾個數就能找到規律。get

看上面這張圖,仔細觀察顏色相同的下劃線標註的位置。好像成2的倍數的數他們的結果相同。好像還有點什麼,那麼咱們就把每一個數拆分紅二進制數,找到他們在輸出中的位置,仔細觀察。數學

將上圖中二進制數對應的結果進行比對,再與二進制數自己的特徵加以比較,發現最終的結果與n對應的二進制數中的1的個數有關。由此,得出了最終規律。it

5.總結一下,規律爲n對應的二進制數中1的個數k,答案爲2^k

C++代碼

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
/*打表
const int N = 1000;
ll c[N][N];
int n;
ll res[N];
void init()
{
    for(int i = 0; i < N;i ++)
        for(int j = 0; j <= i; j++)
        {
            if(!j) c[i][j] = 1;
            else
                c[i][j] = (c[i-1][j] + c[i-1][j-1]);
        }
}
int main()
{
    init();
    for(int i = 2; i < N; i++)
    {
        for(int j = 0; j <= i; j++)
        {
            res[i] += (c[i][j] % 2);
        }
        cout << "res[" << i << "] = " << res[i] << endl;
    }
}
*/
ll n;
int main()
{
    cin >> n;
    ll res = 1;
    while(n)
    {
        if(n & 1) res <<= 1;
        n >>= 1;
    }
    cout << res ;
    return 0;
}

代碼中求組合數的模板來源於yxc大佬的數學知識模板

相關文章
相關標籤/搜索