Find the amount of water in ith cup in a pyramid structure?

后端 未结 6 1570
猫巷女王i
猫巷女王i 2020-12-15 12:12

This question was asked in a forum. Any suggestions?

There is a pyramid with 1 cup at level , 2 at level 2 , 3 at level 3 and so on.. It looks something like this

6条回答
  •  爱一瞬间的悲伤
    2020-12-15 12:53

    The pascal triangle solution for calculating binomial coefficient can be used to solve this problem. We just need to tweak the algorithm a little bit and instead of calculating binomial coefficients, we calculate the water level. Given ith cup, we calculate level and index to find out where the cup sits in the triangle.

    The cups are modelled as

        0         Level 1
      1   2       Level 2
    3   4   5     Level 3
    

    getIndex() and getLevel() returns the index and level. Index and Level starts at 1.

    public static int getIndex(int i) {
        int totalNodes = i + 1;
        double d = (-3 + Math.sqrt(9 - 8*(1-totalNodes)))/2;
        int level = (int)Math.floor(d);
        int total = ((level+1)*(level+2))/2;
        int index = 0;
        if(total==totalNodes) index = level;
        else{
            level++;
            index = totalNodes - total - 1;
        }
    
        return ++index;
    }
    
    public static int getLevel(int i) {
        int totalNodes = i + 1;
        double d = (-3 + Math.sqrt(9 - 8*(1-totalNodes)))/2;
        int level = (int)Math.floor(d);
        int total = ((level+1)*(level+2))/2;
        int index = 0;
        if(total==totalNodes) index = level;
        else{
            level++;
            index = totalNodes - total - 1;
        }
    
        return ++level;
    }
    

    k is kth cup starting at 0. C is cup capacity, L is total water.

    public static double getWaterLevel(double C, double L, int k) {
        int n = getLevel(k);
        int index = getIndex(k);
        double[] water = new double[index+1];
    
        water[1] = L;
    
        for(int i = 2; i <= n; i++)
        {
            boolean overflowed = false;
    
            for(int j = Math.min(i, index); j > 0; j--) {
                double over = 0;
                if(water[j]>C) over = (water[j]-C)/2;
                if(water[j-1]>C) over += (water[j-1]-C)/2;
    
                water[j] = over;
    
                if(!overflowed && over!=0) overflowed=true;
            }
    
            if(!overflowed) break; // no more overflow. stop 
        }
    
        return water[index] > C ? C : water[index];
    }
    

提交回复
热议问题