机器人塔
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 , 不能通过工程设置而省略常用头文件。
提交时,注意选择所期望的编译器类型。
解题思路:
通过输入的A,B的值先确定 塔的层数,因为题目说明了保证人数的合理性,无论A,B给多少人,能堆出来的塔的层数一定是唯一确定的。然后从第一层到最后一层一次遍历,找到符合条件的数组塔,然后筛选出塔中A和B 的数目和给定的A,B数目相同的塔的数量。
#include<iostream>
using namespace std;
int A,B;
char arr[500][500];//数组塔
int deep=0;//塔的深度
char ab[2]={'A','B'};
int count=0;//符合条件的数目
bool isOk(int x,int y){//判断(x,y)位置的放置的A或B是否符合条件
if(x==0||y==0){
return true;
}else{
if(arr[x-1][y-1]=='A'){
if(arr[x][y-1]!=arr[x][y]){
return false;
}
}else{
if(arr[x][y-1]==arr[x][y]){
return false;
}
}
}
return true;
}
bool isTrue(){//判断该塔里A,B的数目是否和输入的A,B数目一样
int x=0,y=0;
for(int i=0;i<deep;i++){
for(int j=0;j<=i;j++){
if(arr[i][j]=='A'){
x++;
}
if(arr[i][j]=='B'){
y++;
}
}
}
if(x==A&&y==B){
return true;
}
return false;
}
void dfs(int i,int j){//递归找出所有的塔
if(i==deep){
if(isTrue()){
count++;
}
}else{
for(int k=0;k<2;k++){
arr[i][j]=ab[k];
if(isOk(i,j)){
if(j<i){
dfs(i,j+1);
}else{
dfs(i+1,0);
}
}
}
}
}
int main(){
cin>>A>>B;
int s=A+B;
int sum=0;
for(int i=1;i<s;i++){//找到层数
sum+=i;
if(sum==s){
deep=i;
break;
}
}
dfs(0,0);
cout<<count<<endl;
}
之前的代码太麻烦了,再看的时候又写了一种简洁一点的:
#include<iostream>
#include<cstring>
using namespace std;
char arr[501][501];
char v[2]={'A','B'};
int r[2];//A ,B 机器人塔的数目
int num;//塔的深度
int sum=0;//符合条件的种类数
void dfs(int row,int col){
if(row<1){
sum++;
return;
}else{
if(row==num){
for(int i=0;i<2;i++){
if(r[i]-1>-1){
arr[row][col]=v[i];
r[i]--;
if(col==row)
dfs(row-1,1);
dfs(row,col+1);
arr[row][col]='C';
r[i]++;
}
}
}else{
if(arr[row+1][col]==arr[row+1][col+1]){
if(r[0]-1>-1){
arr[row][col]=v[0];
r[0]--;
if(col==row)
dfs(row-1,1);
dfs(row,col+1);
arr[row][col]='C';
r[0]++;
}
}
if(arr[row+1][col]!=arr[row+1][col+1]){
if(r[1]-1>-1){
arr[row][col]=v[1];
r[1]--;
if(col==row)
dfs(row-1,1);
dfs(row,col+1);
arr[row][col]='C';
r[1]++;
}
}
}
}
}
int main(){
cin>>r[0]>>r[1];//输入A的个数,B的个数
memset(arr,'C',sizeof(arr));//将塔初始化
// (1+k)*k/2=r[0]+r[1] 下面的for循环是为了找到这个k
int n=(r[0]+r[1])*2;
for(int i=1;i<1000;i++){
if(i*(i+1)==n){//根据等差数列公式找到塔应有的深度
num=i;
break;
}
}
dfs(num,1);//从最底层向上排
cout<<sum<<endl;
return 0;
}