机器人塔【第七届】【决赛】

本文介绍了一种关于机器人塔表演的编程问题,探讨如何利用A和B型机器人遵循特定规则排列成不同塔样式的计算方法,通过DFS算法求解给定A和B数量时可能的组合总数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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
本题思路

基本思路就是列举最后一层的数据,然后在最后一层确定的基础上,按照规则模拟,如果可行放入set中(可以去重),最后输出set的长度就是答案

dfs这题可以用dfs直接暴力出来,主要问题其实是在于突破题意,如果按照常规,我们放入数组,然后一个个组合,这样时间耗时是巨大的,所以我们通过题意可以发现,其实每一点的状态就两种A or B那么其实我们对每一位只要模拟两次,这样就很快了,然后就是其实确认的最后一层其实就确认了整个机器人塔,也就是我们去重的时候只存最后一层即可,但是这个代码只能过83%,第四个测试点无法通过,如果发现问题欢迎留言指正。

下面上代码

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.HashSet;
import java.util.Set;

public class Main机器人塔 {
	static int n,m,q,aa[][];
	static Set<String> set=new HashSet<String>();
	public static void main(String[] args) throws IOException {
		StreamTokenizer x=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
		PrintWriter out=new PrintWriter(System.out);
		x.nextToken();
		n=(int)x.nval;
		x.nextToken();
		m=(int)x.nval;
		q=((int)Math.sqrt(1+4*2*(n+m))-1)/2;//按照等差数列和公式推出
		aa=new int[q][];//动态创建数组
		for(int i=0;i<q;i++)
			aa[i]=new int[i+1];
		dfs(n,m,0);//dfs
		out.println(set.size());
		out.flush();
	}
	public static void dfs(int a,int b,int l) {
		if(l==q) {//如果达到最底层的长度那么就开始验证是否可行
			if(check(a,b)) {//可行
			StringBuilder sb = new StringBuilder();//放入set
			for (int i = 0; i < l; i++) {
				sb.append(aa[l-1][i]);
			}
			set.add(sb.toString());
			}
			return;
		}
		for(int i=0;i<2;i++) {
			if(i==0) {//这个位置为A
				aa[q-1][l]=0;
				dfs(a-1,b,l+1);
			}
			else {//这个位置为B
				aa[q-1][l]=1;
				dfs(a,b-1,l+1);
			}
		}
	}
	public static boolean check(int a,int b) {
		for(int i=q-2;i>=0;i--) {//开始填入
			for(int j=0;j<aa[i].length;j++) {
				if(aa[i+1][j]!=aa[i+1][j+1]) {//说明只能填B
					if(b>0) {
						aa[i][j]=1;
						b--;
					}
					else//不满足则不能组成
						return false;
				}
				else if(aa[i+1][j]==aa[i+1][j+1]) {//只能A
					if(a>0) {
						aa[i][j]=0;
						a--;
					}
					else
						return false;
				}
			}
		}
		return true;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值