2016蓝桥杯决赛 机器人塔(深搜DFS)

题目:

机器人塔

X星球的机器人表演拉拉队有两种服装,A和B。 他们这次表演的是搭机器人塔。

类似:

     A
    B B
   A B A
  A A B B
 B B B A B
A B A B B A
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

队内的组塔规则是:
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;
}


原文http://blog.csdn.net/riba2534/article/details/72547738

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值