题目描述
题目出处:https://www.lanqiao.cn/problems/118/learning/
X 星球的机器人表演拉拉队有两种服装,A 和 B。
他们这次表演的是搭机器人塔。
类似:
A
B B
A B A
A A B B
B B B A B
A B A B B A
队内的组塔规则是:
A 只能站在 AA 或 BB 的肩上。
B 只能站在 AB 或 BA 的肩上。
你的任务是帮助拉拉队计算一下,在给定 A 与 B 的人数时,可以组成多少种花样的塔。
输入描述
输入一行两个整数 M,N(0<M,N<500),分别表示 A、B 的人数,保证人数合理性。
输出描述
要求输出一个整数,表示可以产生的花样种数。
输入输出样例
示例
输入
1 2
输出
3
运行限制
最大运行时间:1s
最大运行内存: 256M
思路
转化:
#include <bits/stdc++.h>
using namespace std;
int n,m;//A,B的人数
int nbit(int num) {
int ans = 0;
while (num) {
num = (num - 1) & num;
ans++;
}
return ans;
}
bool check(int now, int floor) {
int num_a = 0,num_b = 0;
for (int i = floor; i >= 1; i--) {//i是层数也是机器人个数
int count1 = nbit(now);//now里面有多少1
num_b += count1;
num_a += i - count1;//now里面有多少0
//下面开始求上一层的now
now ^= now >> 1;
now &= (1 << (i - 1)) - 1;//消掉高位
if (num_a > m || num_b >> n) return false;//可以提升一点性能
}
return num_a == m && num_b == n;
}
int main() {
cin >> m >> n;
int floor = sqrt((n + m) * 2);//底层人数 == 层数
int ans = 0;
//2的floor次方种排列方案,每一种方案表示为i
for (int i = 0; i < (1 << floor); i++) {
if (check(i, floor)) ans++;
}
cout << ans << endl;
return 0;
}