题目:
机器人塔
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 , 不能通过工程设置而省略常用头文件。提交时,注意选择所期望的编译器类型。
思路:
因为这个三角形满足每一层都比上一层多1,题目的数据范围是m+n最大是1000,所以三角形的层数不超过50层,先把多少层需要多少个字母打个表,然后根据题上给的m,n得到一共有多少层
然后从最下面一层枚举所有情况,上面的可以由下面的推出来,每一次都判断得到的三角形是不是满足题目上给的A和B的个数,然后来进行累加ans
代码:
#include<cstdio>
#include<cstring>
#include<cctype>
#include<string>
#include<set>
#include<iostream>
#include<stack>
#include<cmath>
#include<queue>
#include<vector>
#include<algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
#define mod 10000007
#define debug() puts("whatthefuck!!!")
#define N 1111111
#define M 1000000
#define ll longlong
using namespace std;
int a[1100];
char s1[1000],s2[1000];
int vis[1000];
int n,m,k,ans;
void init()
{
int sum=0;
for(int i=1;i<=50;i++)
{
sum+=i;
a[i]=sum;
}
}
int judge(int t)//判断当前的状况是不是满足条件
{
strcpy(s2+1,s1+1);
int sum_a=0,sum_b=0;
while(t)
{
for(int i=1;i<=t;i++)
{
if(s2[i]=='A')sum_a++;
if(s2[i]=='B')sum_b++;
}
for(int i=1;i<=t-1;i++)
{
if(s2[i]==s2[i+1])
s2[i]='A';
else
s2[i]='B';
}
t--;
}
if(sum_a==m&&sum_b==n)
return 1;
return 0;
}
void dfs(int cnt)
{
if(cnt==k+1)
{
if(judge(k))
ans++;
return;
}
if(!vis[cnt])
{
vis[cnt]=1;
s1[cnt]='A';
dfs(cnt+1);
s1[cnt]='B';
dfs(cnt+1);
vis[cnt]=0;
}
}
int main()
{
init();
scanf("%d%d",&m,&n);
ans=0;
for(int i=0;i<=50;i++)
{
if(a[i]==n+m)
{
k=i;//把当前的层数求出来(层数=最后一行的个数)
break;
}
}
dfs(1);
printf("%d\n",ans);
return 0;
}