2016 蓝桥杯 国赛 JAVA A组第四题 机器人塔

机器人塔




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








请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。




所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。






思路:从上到下遍历,第一层只有一个,为A或B,上面的a[i][j]可以决定下面a[i+1][j]和a[i+1][i+1]的情况,当a[i+1][j]中j=0时,决定
a[i+1][j]和a[i+1][j+1],但是j!=时,a[i+1][j]已经存在,所以只能决定a[i+1][j+1]

当A和B的数量都为0时,即为一种情况,结果加1


package 总决赛;
import java.io.*;
import java.util.Scanner;
public class 机器人塔 {
static int re = 0;//最后结果
//先根据输入的m+n求总共多少层
static int cs(int m,int n){
	int num = m+n,c = 0;
		for(int i=1;i<num;i++){
			c += i;
			if(c == num)
				return i;
		}
		return 0;
}
//                             0      0     
static void dfs(char a[][],int cm,int cn,int M,int N,int d){//
	//参数列表从左到右依次为:存所有A和B的数组,当前递归所在的行号、列号,A和B剩余的个数,当前递归的层数(一开始要赋1)
	//从上到下递归
	if(M <0 || N<0)
		return;
	if(M == 0 && N==0 )
	{
		re++;
		return;
	}
	
		if(cn ==0){
			if(a[cm][cn] == 'A'){//下面两个为AA或BB
				a[cm+1][cn] = a[cm+1][cn+1] = 'A';
				dfs(a,cm+(cn+1)/d,(cn+1)%d,M-2,N,d+(cn+1)/d);
				a[cm+1][cn] = a[cm+1][cn+1] = 'B';
				dfs(a,cm+(cn+1)/d,(cn+1)%d,M,N-2,d+(cn+1)/d);
			}
			else{//下面两个为AB或BA
				a[cm+1][cn] = 'B';a[cm+1][cn+1] = 'A';
				dfs(a,cm+(cn+1)/d,(cn+1)%d,M-1,N-1,d+(cn+1)/d);
				a[cm+1][cn] = 'A';a[cm+1][cn+1] = 'B';
				dfs(a,cm+(cn+1)/d,(cn+1)%d,M-1,N-1,d+(cn+1)/d);
			}
		}
		else{
			if(a[cm][cn] == 'A'){
				if(a[cm+1][cn] == 'A'){//a[cm+1][cn+1]一定为A
					a[cm+1][cn+1] = 'A';
					dfs(a,cm+(cn+1)/d,(cn+1)%d,M-1,N,d+(cn+1)/d);
				}
				else{//a[cm+1][cn]一定为B
					a[cm+1][cn+1] = 'B';
					dfs(a,cm+(cn+1)/d,(cn+1)%d,M,N-1,d+(cn+1)/d);
				}
			}
			else{
				if(a[cm+1][cn] == 'A'){//a[cm+1][cn]一定为B
					a[cm+1][cn+1] = 'B';
					dfs(a,cm+(cn+1)/d,(cn+1)%d,M,N-1,d+(cn+1)/d);
				}
				else{//a[cm+1][cn]一定为A
					a[cm+1][cn+1] = 'A';
					dfs(a,cm+(cn+1)/d,(cn+1)%d,M-1,N,d+(cn+1)/d);
				}
			}
		}
	
		
}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner s = new Scanner(System.in);
		int M = s.nextInt(),N = s.nextInt();
		int c = cs(M,N);
//		System.out.println(c);
		char a[][] = new char [c][];
		for(int i=0;i<c;i++){
			a[i] = new char[i+1];
		}
		a[0][0] = 'A';
		dfs(a,0,0,M-1,N,1);
		a[0][0] = 'B';
		dfs(a,0,0,M,N-1,1);
		System.out.println(re);
	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值