蓝桥杯第七届决赛(国赛)C++B组 第四题 机器人塔


机器人塔

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 <xxx>, 不能通过工程设置而省略常用头文件。

提交时,注意选择所期望的编译器类型。

 

  

  

  这道题确实有点恶心,开始想了好多办法都错了。。。。比如列举底层全排列,显然有重有漏。底层dp基本没结果。

  不过可以确定,不论是从底层开始该排列唯一。从顶层开始则为DFS,这里不进行证明!

说一下思路,顶层开始每一个位置都是 A或者B,尝试AB推导法则:

          仔细观察,每层第i个和上层第i个有异或运算A^B=B ,A^A=A,B^B=A,B^A=B。   好了,本题基本结束。

              map[line][i]=map[line][i-1]^map[line-1][i-1];

  解题时间(2.5hour)

//代码思路

//0表A,1表B,存在二维数组map中,进行DFS
//每一行的上层确定并且每行第一个数字确定,该行唯一
//所以本题就是DFS每行第一个


//题意,A和B的总数cnt<999,设一共可以摆n行,等差数列求和 cnt=n*n(n+1)/2
//得到n最大为44

  不懂再问,下面给出代码:

#include<iostream> 
#include<algorithm>
#include<cmath>
#include<cstring>
#include<set>
#include<stdio.h>
#define ll long long 
using namespace std;
int ans;
int map[50][50];        
void DFS(int line,int re_A,int re_B,int n)    //line 当前行 re_A 可用的A   re_B 可用的B  n代表层数
{
	int A=re_A;
	int B=re_B;
	
	if(re_A<0||re_B<0)
		return;
	if(line == n&&A==0&&B==0)
	{
		ans++;
		return;
	}
		re_A=A;
		re_B=B;
		map[line][0]=0;
		re_A-=1;
		for(int i=1;i<=line;i++)
		{
			map[line][i]=map[line][i-1]^map[line-1][i-1];
			if(map[line][i]==0){
			
				re_A--;
			}
			else{
			
				re_B--;
			}
		}
		DFS(line+1,re_A,re_B,n);
		
		
		
		re_A=A;
		re_B=B;
		map[line][0]=1;
		
		re_B-=1;
		for(int i=1;i<=line;i++)
		{
			map[line][i]=map[line][i-1]^map[line-1][i-1];
			if(map[line][i]==0)
				re_A--;
			else
				re_B--;
		}
		DFS(line+1,re_A,re_B,n);
	
}
int main()
{
	int x,y,n;
	while(cin>>x>>y)
	{
		ans=0;
		for(int i=1;;i++)
		{
			if(2*x+2*y==i*i+i)
			{
				n=i;
				break;
			}
		}
		DFS(0,x,y,n);
		
		cout<<ans<<endl;
		
	}
}

  

 

posted @ 2018-05-13 01:34  会飞的雅蠛蝶  阅读(317)  评论(0编辑  收藏  举报