1. 程式人生 > >Wannafly挑戰賽29-A御阪美琴 (dfs+map)

Wannafly挑戰賽29-A御阪美琴 (dfs+map)

連結:https://ac.nowcoder.com/acm/contest/271/A
來源:牛客網

御阪美琴 時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 131072K,其他語言262144K
64bit IO Format: %lld

題目描述

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

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

輸入描述:

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

輸出描述:

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

輸入

複製
4 1
5

輸出

複製
ham

備註:

1 ≤ n ≤ 10
18
, 1 ≤ m ≤ 10
5
, 1 ≤ a
i
 ≤ 10
18


思路:用dfs找出所有能分出堆玩偶數目的情況,並用map標記為1,然後每輸入一個數進行判斷是否可以map是否為1,如果不為1,表示無法分出該結果。再判斷一下m堆玩偶的總數是否n,可否分為m堆即可。
注意需要剪枝一下,否則會超時。

#include<cstdio>
#include
<cstring> #include<algorithm> #include<iostream> #include<string> #include<vector> #include<stack> #include<bitset> #include<cstdlib> #include<cmath> #include<set> #include<list> #include<deque> #include<map> #include<queue> using namespace std; typedef long long ll; const double PI = acos(-1.0); const double eps = 1e-6; const int INF = 0x3f3f3f3f; const ll mod=1e9+7; ll n,m,a[100005]; map<ll,int> mp; void init(ll x) { if(mp[x]==1) //說明x已經標記過了,不用再遞迴下去了,不能去除,否則超時。 return; mp[x]=1; if(x==1) return; ll u=x/2,v=x-x/2; init(u); init(v); return; } int main() { ios_base::sync_with_stdio(false); cin.tie(0); cin>>n>>m; init(n); ll sum=0,flag=0; for(int i=1;i<=m;i++) { cin>>a[i]; if(sum<=n) sum+=a[i]; if(sum>n) flag=1; if(mp[a[i]]==0) flag=1; } if(flag||m>n||sum!=n) { cout<<"ham"<<endl; return 0; } else cout<<"misaka"<<endl; return 0; }