📜  程序查找给定玻璃杯中的水量

📅  最后修改于: 2021-04-23 18:53:47             🧑  作者: Mango

有些眼镜的容量等于1升。眼镜的存放方法如下:

1
                 2   3
              4    5    6
            7    8    9   10

您可以将水倒入唯一的顶部玻璃杯中。如果您在第一个玻璃杯中放了超过1升的水,则第二个和第三个玻璃杯中的水会溢出并均匀地填充。玻璃5将从第二玻璃和第三玻璃中取水,依此类推。
如果您有X升水,然后将其放在顶玻璃杯中,那么第i排第j杯玻璃中会容纳多少水?
例子。如果您将2升放在顶部。
1 – 1升
2 – 1/2升
3 – 1/2升

2公升水

该方法类似于Pascal三角形的方法2。如果我们仔细研究这个问题,这个问题可以归结为帕斯卡的三角形。

1   ---------------- 1
                 2   3 ---------------- 2
                      4    5    6  ------------ 3
            7    8    9   10  --------- 4

每个玻璃杯都有助于两个玻璃杯。最初,我们将所有水倒入第一杯中。然后,将1升(或少于1升)的水倒入其中,并将剩下的水倒入两杯中。我们对两副眼镜和所有其他眼镜遵循相同的过程,直到第i行为止。到第i行为止,将有i *(i + 1)/ 2杯。

C++
// Program to find the amount of water in j-th glass
// of i-th row
#include 
#include 
#include 
 
// Returns the amount of water in jth glass of ith row
float findWater(int i, int j, float X)
{
    // A row number i has maximum i columns. So input
    // column number must be less than i
    if (j > i)
    {
        printf("Incorrect Inputn");
        exit(0);
    }
 
    // There will be i*(i+1)/2 glasses till ith row
    // (including ith row)
    float glass[i * (i + 1) / 2];
 
    // Initialize all glasses as empty
    memset(glass, 0, sizeof(glass));
 
    // Put all water in first glass
    int index = 0;
    glass[index] = X;
 
    // Now let the water flow to the downward glasses
    // till the row number is less than or/ equal to i (given row)
    // correction : X can be zero for side glasses as they have lower rate to fill
    for (int row = 1; row <= i ; ++row)
    {
        // Fill glasses in a given row. Number of
        // columns in a row is equal to row number
        for (int col = 1; col <= row; ++col, ++index)
        {
            // Get the water from current glass
            X = glass[index];
 
            // Keep the amount less than or equal to
            // capacity in current glass
            glass[index] = (X >= 1.0f) ? 1.0f : X;
 
            // Get the remaining amount
            X = (X >= 1.0f) ? (X - 1) : 0.0f;
 
            // Distribute the remaining amount to
            // the down two glasses
            glass[index + row] += X / 2;
            glass[index + row + 1] += X / 2;
        }
    }
 
    // The index of jth glass in ith row will
    // be i*(i-1)/2 + j - 1
    return glass[i*(i-1)/2 + j - 1];
}
 
// Driver program to test above function
int main()
{
    int i = 2, j = 2;
    float X = 2.0; // Total amount of water
 
    printf("Amount of water in jth glass of ith row is: %f",
            findWater(i, j, X));
 
    return 0;
}


Java
// Program to find the amount
/// of water in j-th glass
// of i-th row
import java.lang.*;
 
class GFG
{
// Returns the amount of water
// in jth glass of ith row
static float findWater(int i, int j,
                       float X)
{
// A row number i has maximum i
// columns. So input column
// number must be less than i
if (j > i)
{
    System.out.println("Incorrect Input");
    System.exit(0);
}
 
// There will be i*(i+1)/2 glasses
// till ith row (including ith row)
int ll = Math.round((i * (i + 1) ));
float[] glass = new float[ll + 2];
 
// Put all water in first glass
int index = 0;
glass[index] = X;
 
// Now let the water flow to the
// downward glasses till the row
// number is less than or/ equal
// to i (given row)
// correction : X can be zero for side
// glasses as they have lower rate to fill
for (int row = 1; row <= i ; ++row)
{
    // Fill glasses in a given row. Number of
    // columns in a row is equal to row number
    for (int col = 1;
             col <= row; ++col, ++index)
    {
        // Get the water from current glass
        X = glass[index];
 
        // Keep the amount less than or
        // equal to capacity in current glass
        glass[index] = (X >= 1.0f) ? 1.0f : X;
 
        // Get the remaining amount
        X = (X >= 1.0f) ? (X - 1) : 0.0f;
 
        // Distribute the remaining amount 
        // to the down two glasses
        glass[index + row] += X / 2;
        glass[index + row + 1] += X / 2;
    }
}
 
// The index of jth glass in ith
// row will be i*(i-1)/2 + j - 1
return glass[(int)(i * (i - 1) /
                   2 + j - 1)];
}
 
// Driver Code
public static void main(String[] args)
{
    int i = 2, j = 2;
    float X = 2.0f; // Total amount of water
    System.out.println("Amount of water in jth " +
                         "glass of ith row is: " +
                              findWater(i, j, X));
}
}
 
// This code is contributed by mits


Python3
# Program to find the amount
# of water in j-th glass of
# i-th row
 
# Returns the amount of water
# in jth glass of ith row
def findWater(i, j, X):
    # A row number i has maximum
    # i columns. So input column
    # number must be less than i
    if (j > i):
        print("Incorrect Input");
        return;
 
    # There will be i*(i+1)/2
    # glasses till ith row
    # (including ith row)
    # and Initialize all glasses
    # as empty
    glass = [0]*int(i *(i + 1) / 2);
 
    # Put all water
    # in first glass
    index = 0;
    glass[index] = X;
 
    # Now let the water flow to
    # the downward glasses till
    # the row number is less
    # than or/ equal to i (given
    # row) correction : X can be
    # zero for side glasses as
    # they have lower rate to fill
    for row in range(1,i):
        # Fill glasses in a given
        # row. Number of columns
        # in a row is equal to row number
        for col in range(1,row+1):
            # Get the water
            # from current glass
            X = glass[index];
 
            # Keep the amount less
            # than or equal to
            # capacity in current glass
            glass[index] = 1.0 if (X >= 1.0) else X;
 
            # Get the remaining amount
            X = (X - 1) if (X >= 1.0) else 0.0;
 
            # Distribute the remaining
            # amount to the down two glasses
            glass[index + row] += (X / 2);
            glass[index + row + 1] += (X / 2);
            index+=1;
 
    # The index of jth glass
    # in ith row will
    # be i*(i-1)/2 + j - 1
    return glass[int(i * (i - 1) /2 + j - 1)];
 
# Driver Code
if __name__ == "__main__":
     
    i = 2;
    j = 2;
    X = 2.0;
# Total amount of water
 
    res=repr(findWater(i, j, X));
    print("Amount of water in jth glass of ith row is:",res.ljust(8,'0'));
# This Code is contributed by mits


C#
// Program to find the amount
// of water in j-th glass
// of i-th row
using System;
 
class GFG
{
// Returns the amount of water
// in jth glass of ith row
static float findWater(int i, int j,
                       float X)
{
// A row number i has maximum i
// columns. So input column
// number must be less than i
if (j > i)
{
    Console.WriteLine("Incorrect Input");
    Environment.Exit(0);
}
 
// There will be i*(i+1)/2 glasses
// till ith row (including ith row)
int ll = (int)Math.Round((double)(i * (i + 1)));
float[] glass = new float[ll + 2];
 
// Put all water in first glass
int index = 0;
glass[index] = X;
 
// Now let the water flow to the
// downward glasses till the row
// number is less than or/ equal
// to i (given row)
// correction : X can be zero
// for side glasses as they have
// lower rate to fill
for (int row = 1; row <= i ; ++row)
{
    // Fill glasses in a given row.
    // Number of columns in a row
    // is equal to row number
    for (int col = 1;
            col <= row; ++col, ++index)
    {
        // Get the water from current glass
        X = glass[index];
 
        // Keep the amount less than
        // or equal to capacity in
        // current glass
        glass[index] = (X >= 1.0f) ?
                              1.0f : X;
 
        // Get the remaining amount
        X = (X >= 1.0f) ? (X - 1) : 0.0f;
 
        // Distribute the remaining amount
        // to the down two glasses
        glass[index + row] += X / 2;
        glass[index + row + 1] += X / 2;
    }
}
 
// The index of jth glass in ith
// row will be i*(i-1)/2 + j - 1
return glass[(int)(i * (i - 1) /
                   2 + j - 1)];
}
 
// Driver Code
static void Main()
{
    int i = 2, j = 2;
    float X = 2.0f; // Total amount of water
    Console.WriteLine("Amount of water in jth " +
                        "glass of ith row is: " +
                             findWater(i, j, X));
}
}
 
// This code is contributed by mits


PHP
 $i)
    {
        echo "Incorrect Input\n";
        return;
    }
 
    // There will be i*(i+1)/2
    // glasses till ith row
    // (including ith row)
    // and Initialize all glasses
    // as empty
    $glass = array_fill(0, (int)($i *
                       ($i + 1) / 2), 0);
 
    // Put all water
    // in first glass
    $index = 0;
    $glass[$index] = $X;
 
    // Now let the water flow to
    // the downward glasses till
    // the row number is less
    // than or/ equal to i (given 
    // row) correction : X can be
    // zero for side glasses as
    // they have lower rate to fill
    for ($row = 1; $row < $i ; ++$row)
    {
        // Fill glasses in a given
        // row. Number of columns
        // in a row is equal to row number
        for ($col = 1;
             $col <= $row; ++$col, ++$index)
        {
            // Get the water
            // from current glass
            $X = $glass[$index];
 
            // Keep the amount less
            // than or equal to
            // capacity in current glass
            $glass[$index] = ($X >= 1.0) ?
                                     1.0 : $X;
 
            // Get the remaining amount
            $X = ($X >= 1.0) ?
                    ($X - 1) : 0.0;
 
            // Distribute the remaining
            // amount to the down two glasses
            $glass[$index + $row] += (double)($X / 2);
            $glass[$index + $row + 1] += (double)($X / 2);
        }
    }
 
    // The index of jth glass
    // in ith row will
    // be i*(i-1)/2 + j - 1
    return $glass[(int)($i * ($i - 1) /
                          2 + $j - 1)];
}
 
// Driver Code
$i = 2;
$j = 2;
$X = 2.0; // Total amount of water
echo "Amount of water in jth " ,
        "glass of ith row is: ".
       str_pad(findWater($i, $j,
                   $X), 8, '0');
 
// This Code is contributed by mits
?>


Javascript


C++
// CPP program for above approach
#include
using namespace std;
 
// Program to find the amount 
// of water in j-th glass
// of i-th row
void findWater(float k, int i, int j)
{
     
    // stores how much amount of water
    // present in every glass 
    float dp[i+1][2*i + 1];
    bool vis[i+1][2*i + 1];
     
    // initialize dp and visited arrays
    for(int n=0;n>q;
    dp[0][i] = k;
     
    // we take the center of the first row for
    // the location of the first glass
    q.push({0,i});
    vis[0][i] = true;
     
    // this while loop runs unless the queue is not empty
    while(!q.empty())
    {
        // First we remove the pair from the queue
        pairtemp = q.front();
        q.pop();
        int n = temp.first;
        int m = temp.second;
         
         
        // as we know we have  to calculate the
        // amount of water in jth glass
        // of ith row . so first we check if we find solutions
        // for the the every glass of i'th row.
        // so, if we have calculated the result
        // then we break the loop
        // and return our answer
        if(i == n)
            break;
             
             
        float x = dp[n][m];
        if(float((x-1.0)/2.0) < 0)
        {
            dp[n+1][m-1] += 0;
            dp[n+1][m+1] += 0;
        }
        else
        {
            dp[n+1][m-1] += float((x-1.0)/2.0);
            dp[n+1][m+1] += float((x-1.0)/2.0);   
        }
        if(vis[n+1][m-1]==false)
        {
            q.push({n+1,m-1});
            vis[n+1][m-1] = true;
        }
        if(vis[n+1][m+1]==false)
        {
            q.push({n+1,m+1});
            vis[n+1][m+1] = true;
        }
    }
    
    if(dp[i-1][2*j-1]>1)
        dp[i-1][2*j-1] = 1.0;
         
    cout<<"Amount of water in jth glass of ith row is: ";
     
    // print the result for jth glass of ith row
    cout<water in litres
    float k; 
    cin>>k;
   
    //i->rows  j->cols
    int i,j;
    cin>>i>>j; 
   
    // Function Call 
    findWater(k,i,j);
    return 0;
}
 
 // This code is contibuted by Sagar Jangra and Naresh Saharan


Java
// Program to find the amount 
/// of water in j-th glass
// of i-th row
import java.io.*;
import java.util.*;
 
// class Triplet which stores curr row
// curr col and curr rem-water
// of every glass
class Triplet
{
  int row;
  int col;
  double rem_water;
  Triplet(int row,int col,double rem_water)
  {
    this.row=row;this.col=col;this.rem_water=rem_water;
  }
}
 
 
class GFG
{
  // Returns the amount of water
  // in jth glass of ith row
  public static double findWater(int i,int j,int totalWater)
  {
 
    // stores how much amount of water present in every glass  
    double dp[][] = new double[i+1][2*i+1];
 
    // store Triplet i.e curr-row , curr-col, rem-water
    Queue queue = new LinkedList<>();
 
    // we take the center of the first row for
    // the location of the first glass
    queue.add(new Triplet(0,i,totalWater));
 
 
    // this while loop runs unless the queue is not empty
    while(!queue.isEmpty())
    {
      // First we remove the Triplet from the queue
      Triplet curr = queue.remove();
 
      // as we know we have  to calculate the
      // amount of water in jth glass
      // of ith row . so first we check if we find solutions
      // for the the every glass of i'th row.
      // so, if we have calculated the result
      // then we break the loop
      // and return our answer
      if(curr.row == i)
        break;
 
      // As we know maximum capacity of every glass
      // is 1 unit. so first we check the capacity
      // of curr glass is full or not.
      if(dp[curr.row][curr.col] != 1.0)
      {
        // calculate the remaining capacity of water for curr glass
        double rem_water = 1-dp[curr.row][curr.col];
 
        // if the remaining capacity of water for curr glass
        // is greater than then the remaining capacity of tatal
        // water then we put all remaining water into curr glass
        if(rem_water > curr.rem_water)
        {
          dp[curr.row][curr.col] += curr.rem_water;
          curr.rem_water = 0;
        }
        else
        {
          dp[curr.row][curr.col] += rem_water;
          curr.rem_water -= rem_water;
        }
      }
 
      // if remaining capacity of tatal water is not equal to
      // zero then we add left and right glass of the next row
      // and gives half capacity of tatal water to both the
      // glass
      if(curr.rem_water != 0)
      {
        queue.add(new Triplet(curr.row + 1,curr.col -
                                  1,curr.rem_water/2.0));
        queue.add(new Triplet(curr.row + 1,curr.col +
                                  1,curr.rem_water/2.0));
      }
    }
 
    // return the result for jth glass of ith row
    return dp[i-1][2*j-1];
  }
 
  // Driver Code
  public static void main (String[] args)
  {
    int i = 2, j = 2;
    int totalWater = 2; // Total amount of water
    System.out.print("Amount of water in jth glass of ith row is:");
    System.out.format("%.6f", findWater(i, j, totalWater));  
  }
 
}
  // this code is contibuted by  Naresh Saharan and Sagar Jangra


输出:

Amount of water in jth glass of ith row is: 0.500000

方法2(使用BFS遍历)

我们将讨论解决此问题的另一种方法。首先,我们在队列中添加一个Triplet(row,col,rem-water),它指示第一个元素的起始值并填充1升水。然后我们简单地应用bfs即,我们将left(row + 1,col-1,rem-water)Triplet和right(row + 1,col + 1,rem-water)Triplet加到队列中,剩下的一半留在第一个三胞胎,另一半进入下一个三胞胎。

以下是此解决方案的实现。

C++

// CPP program for above approach
#include
using namespace std;
 
// Program to find the amount 
// of water in j-th glass
// of i-th row
void findWater(float k, int i, int j)
{
     
    // stores how much amount of water
    // present in every glass 
    float dp[i+1][2*i + 1];
    bool vis[i+1][2*i + 1];
     
    // initialize dp and visited arrays
    for(int n=0;n>q;
    dp[0][i] = k;
     
    // we take the center of the first row for
    // the location of the first glass
    q.push({0,i});
    vis[0][i] = true;
     
    // this while loop runs unless the queue is not empty
    while(!q.empty())
    {
        // First we remove the pair from the queue
        pairtemp = q.front();
        q.pop();
        int n = temp.first;
        int m = temp.second;
         
         
        // as we know we have  to calculate the
        // amount of water in jth glass
        // of ith row . so first we check if we find solutions
        // for the the every glass of i'th row.
        // so, if we have calculated the result
        // then we break the loop
        // and return our answer
        if(i == n)
            break;
             
             
        float x = dp[n][m];
        if(float((x-1.0)/2.0) < 0)
        {
            dp[n+1][m-1] += 0;
            dp[n+1][m+1] += 0;
        }
        else
        {
            dp[n+1][m-1] += float((x-1.0)/2.0);
            dp[n+1][m+1] += float((x-1.0)/2.0);   
        }
        if(vis[n+1][m-1]==false)
        {
            q.push({n+1,m-1});
            vis[n+1][m-1] = true;
        }
        if(vis[n+1][m+1]==false)
        {
            q.push({n+1,m+1});
            vis[n+1][m+1] = true;
        }
    }
    
    if(dp[i-1][2*j-1]>1)
        dp[i-1][2*j-1] = 1.0;
         
    cout<<"Amount of water in jth glass of ith row is: ";
     
    // print the result for jth glass of ith row
    cout<water in litres
    float k; 
    cin>>k;
   
    //i->rows  j->cols
    int i,j;
    cin>>i>>j; 
   
    // Function Call 
    findWater(k,i,j);
    return 0;
}
 
 // This code is contibuted by Sagar Jangra and Naresh Saharan

Java

// Program to find the amount 
/// of water in j-th glass
// of i-th row
import java.io.*;
import java.util.*;
 
// class Triplet which stores curr row
// curr col and curr rem-water
// of every glass
class Triplet
{
  int row;
  int col;
  double rem_water;
  Triplet(int row,int col,double rem_water)
  {
    this.row=row;this.col=col;this.rem_water=rem_water;
  }
}
 
 
class GFG
{
  // Returns the amount of water
  // in jth glass of ith row
  public static double findWater(int i,int j,int totalWater)
  {
 
    // stores how much amount of water present in every glass  
    double dp[][] = new double[i+1][2*i+1];
 
    // store Triplet i.e curr-row , curr-col, rem-water
    Queue queue = new LinkedList<>();
 
    // we take the center of the first row for
    // the location of the first glass
    queue.add(new Triplet(0,i,totalWater));
 
 
    // this while loop runs unless the queue is not empty
    while(!queue.isEmpty())
    {
      // First we remove the Triplet from the queue
      Triplet curr = queue.remove();
 
      // as we know we have  to calculate the
      // amount of water in jth glass
      // of ith row . so first we check if we find solutions
      // for the the every glass of i'th row.
      // so, if we have calculated the result
      // then we break the loop
      // and return our answer
      if(curr.row == i)
        break;
 
      // As we know maximum capacity of every glass
      // is 1 unit. so first we check the capacity
      // of curr glass is full or not.
      if(dp[curr.row][curr.col] != 1.0)
      {
        // calculate the remaining capacity of water for curr glass
        double rem_water = 1-dp[curr.row][curr.col];
 
        // if the remaining capacity of water for curr glass
        // is greater than then the remaining capacity of tatal
        // water then we put all remaining water into curr glass
        if(rem_water > curr.rem_water)
        {
          dp[curr.row][curr.col] += curr.rem_water;
          curr.rem_water = 0;
        }
        else
        {
          dp[curr.row][curr.col] += rem_water;
          curr.rem_water -= rem_water;
        }
      }
 
      // if remaining capacity of tatal water is not equal to
      // zero then we add left and right glass of the next row
      // and gives half capacity of tatal water to both the
      // glass
      if(curr.rem_water != 0)
      {
        queue.add(new Triplet(curr.row + 1,curr.col -
                                  1,curr.rem_water/2.0));
        queue.add(new Triplet(curr.row + 1,curr.col +
                                  1,curr.rem_water/2.0));
      }
    }
 
    // return the result for jth glass of ith row
    return dp[i-1][2*j-1];
  }
 
  // Driver Code
  public static void main (String[] args)
  {
    int i = 2, j = 2;
    int totalWater = 2; // Total amount of water
    System.out.print("Amount of water in jth glass of ith row is:");
    System.out.format("%.6f", findWater(i, j, totalWater));  
  }
 
}
  // this code is contibuted by  Naresh Saharan and Sagar Jangra
输出
Amount of water in jth glass of ith row is:0.500000

时间复杂度: O(2 ^ i)

空间复杂度: O(i ^ 2)