蓝桥杯_排列小球 java

题目描述

小蓝有黄绿蓝三种颜色的小球,分别为R,G,B 个。同样颜色的小球没有区别。

小蓝将这些小球从左到右排成一排,排完后,将最左边的连续同色小球个数记为 t1,将接下来的连续小球个数记为t2,以此类推直到最右边的小球。

请问,总共有多少总摆放小球的方案,使得 t1,t2,⋯ 为严格单调递增序列,即 t1t2t3≤⋯。

输入描述

输入一行包含三个整数 R,G,B

其中,0≤R,G,B≤50。。

输出描述

输出一个整数,表示答案。

输入输出样例

示例 1
输入
3 6 0
输出
3
样例说明

用 r 表示红球,g 表示绿球,可能的方案包括:

rrrgggggg

grrrggggg

ggrrrgggg

运行限制

  • 最大运行时间:1s

  • 最大运行内存: 128M

思路

因为全排列时间复杂度巨大,所以用深搜选择性的查找符合条件的序列
本题可以想象成: 手上拿着这些球,然后往地上放,每次拿与上次不同颜色的小球放,且放的数量必须比上次多,如果最后手上没球了,就记下这个序列;如果最后手上的球在符合规则的情况下放不进去了,就不继续进行了,并且把刚刚放的再拿回来,重新放,如果还不行,就一直往回拿直到可以放另一种情况为止。直到所有情况全部模拟完。

JAVA代码

import java.util.Scanner;

public class 排列小球 {

    static int[] a = new int[3];
    static int count = 0;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int sum = 0;
        for (int i = 0; i < 3; i++) {
            a[i] = scanner.nextInt();
            sum += a[i];
        }
        dfs(sum, 0, -1); // 没放入序列的小球,上一次放的球数,上一次放的球的颜色
        System.out.println(count);
    }

    private static void dfs(int sum, int num, int lastColor) {
        //球全部放完,这是一种情况
        if (sum == 0) {
            count++;
            return;
        }
        
        for (int i = 0; i < 3; i++) {
            if (i == lastColor) {//不能挨着放同种颜色 
                continue;
            }
            for (int j = num + 1; j <= a[i]; j++) {
                a[i] -= j;//减少手上该种颜色的球的数量
                dfs(sum - j, j, i);//j为放入序列的球数 i为这次放的球的颜色 
                a[i] += j;//深搜完一种情况后,恢复手上该颜色球的数量 (回溯)
            }
        }
    }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,你需要使用Java的图形库来创建一个窗口和画布,然后在画布上绘制小球。 为了让小球反弹,你需要跟踪小球的位置、速度和加速度,并在每个时间步更新这些值。 在每个时间步,你需要检查小球是否碰到了画布的边缘。如果小球碰到了边缘,你需要反转小球的速度,使它开始向相反的方向移动。 下面是一个简单的示例代码,它可以让一个小球在画布上反弹: ``` import javax.swing.*; import java.awt.*; import java.awt.event.*; public class BouncingBall extends JPanel implements ActionListener { private int x = 0; private int y = 0; private int xVel = 2; private int yVel = 2; public BouncingBall() { Timer timer = new Timer(5, this); timer.start(); } public void paintComponent(Graphics g) { super.paintComponent(g); g.fillOval(x, y, 30, 30); } public void actionPerformed(ActionEvent e) { x += xVel; y += yVel; if (x < 0 || x > getWidth() - 30) { xVel = -xVel; } if (y < 0 || y > getHeight() - 30) { yVel = -yVel; } repaint(); } public static void main(String[] args) { JFrame frame = new JFrame("Bouncing Ball"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(300, 300); BouncingBall panel = new BouncingBall(); frame.add(panel); frame.setVisible(true); } } ``` 在这个示例中,我们使用了一个计时器来不断更新小球的位置。在每个时间步中,我们通过加上速度来更新小球的位置。然后,我们检查小球是否碰到了画布的边缘,并在需要时反转速度。 最后,我们在 `paintComponent` 方法中绘制小球,并在每个时间步中调用 `repaint` 方法来更新画布。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值