御坂美琴(入門bfs+STL)

                                            御坂美琴

misaka是呱太爺爺的小粉絲,呱太爺爺有一句話說的好:"一尺之棰,日取其半,萬世不竭"。

misaka現在有 n 個呱太玩偶放在一堆,每一次操作,misaka會選擇當前個數 > 1 的一堆呱太玩偶。並將這一堆呱太玩偶分成 兩堆,x 是當前這一堆玩偶的個數。現在 misaka 想將玩偶分成 m 堆,其中第 i 堆呱太玩偶的個數是 ai ,你需要告訴 misaka 是否能通過若干次操作將玩偶分成指定的這 m 堆。如果可以輸出 ,否則輸出

輸入描述:

第一行兩個數 n, m 。
接下來一行 m 個數 ai 。

輸出描述:

輸出共一個字符串 ,表示 misaka 能否將玩偶分成指定的 m 堆。

輸入

4 1
5

輸出

ham

備註:

 1 ≤ n ≤ 10^18, 1 ≤ m ≤ 10^5, 1 ≤ ai ≤ 10^18。

 

題意:

給定n個物品,每次可以將物品分成數量爲的兩堆物品,問是否可以分出一個給定長度爲m的物品數量序列.

題解:

每次都能分成兩堆,用隊列模擬分堆,講可能出現的情況標記一下,最後與所給序列對比,如果完全一樣則輸出misaka否則輸出ham

最後還需要特判一下 所給序列的和不超過n (本以爲這個和會爆ll,然而並沒有)

 

這個題剛開是沒想法,一直以爲是找規律,主要是看到數據很大,但是沒想到他可以用隊列模擬每次一半,可以優化到log級別

另一個坑就是容易爆內存,剛開始的bfs想法是

先把所出現的數都先標記一下,然後與bfs模擬出來的結果相比較,如果相同就cnt++,最後看看cnt是否等於m

然而這種想法,佔用內存太大,,,,

總之一句話,太菜。。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define linf 0x3f3f3f3f3f3f3f3f
ll a[100005];
map<ll,bool>vis;
ll cnt;
ll bfs(ll x)
{
    queue<ll>Q;
    Q.push(x);
    while(!Q.empty())
    {
        ll u=Q.front();
        Q.pop();
        if(vis[u])continue;//如果沒有會爆內存

        vis[u]=1;

        Q.push(u/2);
        Q.push(u-u/2);

    }

    return 0;

}
int main()
{
    ll n,m;
    ll sum=0;
    scanf("%lld%lld",&n,&m);
    for(int i=1; i<=m; i++)
    {
        scanf("%lld",&a[i]);
        sum+=a[i];
    }
    
    if(sum!=n)
    {
        printf("ham\n");
        return 0;
    }

    bfs(n);
    int flag=1;
    for(int i=1; i<=m; i++)
    {
        if(!vis[a[i]])
        {
            flag=0;
            break;
        }
    }
    if(flag)printf("misaka\n");
    else printf("ham\n");

    return 0;
}

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章