链接:https://ac.nowcoder.com/acm/contest/271/A
来源:牛客网
misaka是呱太爷爷的小粉丝,呱太爷爷有一句话说的好:"一尺之棰,日取其半,万世不竭"。
misaka现在有 n 个呱太玩偶放在一堆,每一次操作,misaka会选择当前个数 > 1 的一堆呱太玩偶。并将这一堆呱太玩偶分成 和 两堆,x 是当前这一堆玩偶的个数。现在 misaka 想将玩偶分成 m 堆,其中第 i 堆呱太玩偶的个数是 ai ,你需要告诉 misaka 是否能通过若干次操作将玩偶分成指定的这 m 堆。如果可以输出 ,否则输出 。
1 ≤ n ≤ 1018, 1 ≤ m ≤ 105, 1 ≤ ai ≤ 1018。
这道题就是一个递归但是n很大所以需要简化题目;其中就还通过m来递归n这就是这道题的很关键;
通过map来记录m堆数的情况,然后递归在n的递归下查找看是否存在,且合法,这个递归有两种解法,
1.就是普通的递归写法,往下递归但是要及时判断减少递归时间复杂度;
2,就是使用priority_queue来判断;
代码一:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#define pi acos(-1)
#define e exp(1)
#define For(i, a, b) for(int (i) = (a); (i) <= (b); (i) ++)
#define Bor(i, a, b) for(int (i) = (b); (i) >= (a); (i) --)
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)<(b))?(a):(b))
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define eps 1e-7
#define INF 0x3f3f3f3f
#define inf -2100000000
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxn = 1e5 + 10;
const double EPS = 1e-10;
const ll p = 1e7+9;
const ll mod = 1e9+7;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
inline int read(){
int ret=0,f=0;char ch=getchar();
while(ch>'9'||ch<'0') f^=ch=='-',ch=getchar();
while(ch<='9'&&ch>='0') ret=ret*10+ch-'0',ch=getchar();
return f?-ret:ret;
}
ll n, m;
map<ll, ll>mp;
ll t = 0;
void init(ll t){
if(t == 0){
cout << "ham" <<endl;
exit(0);
}
if(mp[t]){
mp[t]--;
return ;
}
init(t >> 1);
init(t - (t >> 1));
return ;
}
int main(){
ios::sync_with_stdio(false);
cin >> n >> m;
ll sum = 0;
ll a;
for(int i = 0; i< m; i++){
cin >> a;
sum += a;
mp[a]++;
}
if(sum != n){
cout << "ham" << endl;
return 0;
}else{
init(n);
cout << "misaka" << endl;
}
return 0;
}
代码二:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#define pi acos(-1)
#define e exp(1)
#define For(i, a, b) for(int (i) = (a); (i) <= (b); (i) ++)
#define Bor(i, a, b) for(int (i) = (b); (i) >= (a); (i) --)
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)<(b))?(a):(b))
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define eps 1e-7
#define INF 0x3f3f3f3f
#define inf -2100000000
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxn = 100 + 10;
const double EPS = 1e-10;
const ll p = 1e7+9;
const ll mod = 1e9+7;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
inline int read(){
int ret=0,f=0;char ch=getchar();
while(ch>'9'||ch<'0') f^=ch=='-',ch=getchar();
while(ch<='9'&&ch>='0') ret=ret*10+ch-'0',ch=getchar();
return f?-ret:ret;
}
ll n,m;
map<ll, ll>mp;
int main(){
ios::sync_with_stdio(false);
mp.clear();
cin >> n >> m;
ll x;
for(int i = 0; i < m; i++){
cin >> x;
mp[x] ++;
}
priority_queue<ll, vector<ll> >q;
q.push(n);
while(!q.empty()){
ll t = q.top();
q.pop();
if(mp[t]>0){
mp[t] --;
m--;
if(m==0){
break;
}
}else{
q.push(t>>1);
q.push(t-(t>>1));
if(q.size() > m){
break;
}
}
}
if(q.empty() && m == 0){
cout << "misaka" << endl;
}else{
cout << "ham" << endl;
}
return 0;
}