机器人塔
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
再例如:
用户输入:
3 3
程序应该输出:
4
资源约定:
峰值内存消耗 < 256M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include , 不能通过工程设置而省略常用头文件。
提交时,注意选择所期望的编译器类型。
Ideas
按照组塔规则,只要最底下一层的排列确定了,那么从下往上的机器人排列就确定了。
所以我们只需要搜索最底下一层的所有排列情况,然后判断这种情况是否可以利用所有的机器人组成相应的塔结构。
机器人塔每一层的数量是公差为1的等差数列,由求和公式:a1*n+[n*(n-1)*d]/2
,得机器人总数 num = 1 * n + [n * (n - 1)] / 2,其中n表示层数。
设A的人数为num_a,B的人数为num_b,那么 num_a + num_b = 1 * n + [n * (n - 1)] / 2,然后我们可以通过解方程得到机器人塔的层数。
接下来就是正常的DFS的套路了,搜索最下面一层所有排列情况,然后再定义一个check函数用来判断当前排列情况是否满足要求。
Code
C++
#include <cmath>
#include <cstring>
#include <iostream>
using namespace std;
int num_a, num_b, line;
char map[45][45];
long long ans;
bool check() {
int a = 0, b = 0;
for (int i = 1; i < line + 1; i++)
for (int j = 1; j < i + 1; j++)
if (map[i][j] == 'A') a++;
else b++;
if ((a != num_a) || (b != num_b)) return false;
return true;
}
void init() {
for (int i = line; i > 1; i--)
for (int j = 1; j < i; j++)
if (map[i][j] == map[i][j + 1])
map[i - 1][j] = 'A';
else map[i - 1][j] = 'B';
}
void dfs(int y) {
if (y == line + 1) {
init();
if (check()) {
ans++;
}
return;
}
map[line][y] = 'A';
dfs(y + 1);
map[line][y] = 'B';
dfs(y + 1);
}
int main() {
cin >> num_a >> num_b;
int temp = sqrt(1 + 8 * (num_a + num_b));
line = (temp - 1) / 2;
dfs(1);
cout << ans << endl;
return 0;
}
Python
from math import sqrt
maps = [[None] * 50 for _ in range(50)]
def dfs(y):
if y == level:
a, b = 0, 0
for i in range(level - 2, -1, -1):
for j in range(i + 1):
maps[i][j] = 'A' if maps[i + 1][j] == maps[i + 1][j + 1] else 'B'
for i in range(level):
for j in range(i + 1):
if maps[i][j] == 'A':
a += 1
elif maps[i][j] == 'B':
b += 1
if a == num_a and b == num_b:
global ans
ans += 1
return
maps[level - 1][y] = 'A'
dfs(y + 1)
maps[level - 1][y] = 'B'
dfs(y + 1)
if __name__ == '__main__':
ans = 0
num_a, num_b = map(int, input().split())
level = int((sqrt(1 + 8 * (num_a + num_b)) - 1) / 2)
dfs(0)
print(ans)