这都世界杯了,我喝点酒不过分吧?

279 阅读4分钟

同志们,大家好,我是阿良

今日,世界杯已经开始拉开帷幕,在这个程序员的人群中,我相信,应该有不少人会一起看球吧?毕竟,他比赛那个时间,你还没下班

那你看比赛,就盯着看啊,眼动嘴不动,他也难受是不是,不能上去踢球,我看着比赛,吃点喝点,不过分吧?

既然都喝上了,咱们就别对着瓶吹了,优雅永不过时,懂不?

那接下来,就迎接我们的主题!香槟塔!

题目描述:

我们把玻璃杯摆成金字塔的形状,其中 第一层 有 1 个玻璃杯, 第二层 有 2 个,依次类推到第 100 层,每个玻璃杯 (250ml) 将盛有香槟。

从顶层的第一个玻璃杯开始倾倒一些香槟,当顶层的杯子满了,任何溢出的香槟都会立刻等流量的流向左右两侧的玻璃杯。当左右两边的杯子也满了,就会等流量的流向它们左右两边的杯子,依次类推。(当最底层的玻璃杯满了,香槟会流到地板上)

例如,在倾倒一杯香槟后,最顶层的玻璃杯满了。倾倒了两杯香槟后,第二层的两个玻璃杯各自盛放一半的香槟。在倒三杯香槟后,第二层的香槟满了 - 此时总共有三个满的玻璃杯。在倒第四杯后,第三层中间的玻璃杯盛放了一半的香槟,他两边的玻璃杯各自盛放了四分之一的香槟,如下图所示。

示例 1:
输入: poured(倾倒香槟总杯数) = 1, query_glass(杯子的位置数) = 1, query_row(行数) = 1
输出: 0.00000
解释: 我们在顶层(下标是(0,0))倒了一杯香槟后,没有溢出,因此所有在顶层以下的玻璃杯都是空的。

示例 2:
输入: poured(倾倒香槟总杯数) = 2, query_glass(杯子的位置数) = 1, query_row(行数) = 1
输出: 0.50000
解释: 我们在顶层(下标是(0,0)倒了两杯香槟后,有一杯量的香槟将从顶层溢出,位于(1,0)的玻璃杯和(1,1)的玻璃杯平分了这一杯香槟,所以每个玻璃杯有一半的香槟。

示例 3:
输入: poured = 100000009, query_row = 33, query_glass = 17
输出: 1.00000

首先,我们需要分析一下题目,他现在是出于一个倒酒的状态,我们需要知道几个要素,

  • 每层的酒杯递增
  • 在没有倒满之前,每层的液体总数是对称的
  • 处于中间的酒杯最先倒满

由于图片的原因,很多人可能在模拟倒酒得过程中可能会出现问题,本人小白,也没看过现场到香槟塔的,所以在第一次想这个模拟倒酒的过程中也是出现了问题

当上述的问题解决之后,我们就应该考虑怎么用代码去模拟我们倒酒的过程了,

怎么模拟?找杯水去到啊!

先从第一个杯子来看,我们倒水的过程就是,第一个杯子倒满了,之后水流向其他的杯子(这不是废话吗)

那我们流经我们第一个杯子的水量就是poured(倾倒香槟总杯数) 那我们有多少水流到下一个杯子呢?poured(倾倒香槟总杯数)-1

OK,我们知道这个道理以后,我们使用一个二维数组来模拟我们倒水的一个过程,

设置第一个杯子的位置为[0][0],这时候可能就会有疑问了,我们第一个杯子不是在中间吗,这要是[0][0]开始,我们向左的杯子怎么办?那么咱就是说,实际情况的确是,但是,这不是在用代码,模拟吗,在代码中,我们整个香槟塔的位置,都向左移动了,向下流的规则就变成了,正下方和正下方向右一位,就像我们最开始写的九九乘法表一样

class Solution {
    public double champagneTower(int poured, int query_row, int query_glass) {
         double[][] w = new double[query_row+2][query_row+2];
        w[0][0]=poured;
        for (int i=0;i<=query_row;i++){
            for (int j=0;j<=i;j++){
                if(w[i][j]<=1)continue;
                w[i+1][j]+=(w[i][j]-1)/2;
                w[i+1][j+1]+=(w[i][j]-1)/2;
            }
        }
        return Math.min(w[query_row][query_glass],1);
    }
}

在这个方法里面,使用的一个二维数组,便于我们理解,当然,我们也可以使用滚动数组的方式,这样的话会更加的节省空间,甚至,你可以只计算一般的的香槟塔,因为我们的整个香槟塔是对称的,我们寻找杯子的时候只需要进行一个折中的操作。

那最后,不管是因为什么进来的,点个赞再走呗!

别打作者就行!!!

本文正在参加「金石计划 . 瓜分6万现金大奖」