Minimize Rounding Error to Meet Target in C++


Suppose we have an array of prices P [p1,p2...,pn] and a target value, we have to round each price Pi to Roundi(Pi) so that the rounded array [Round1(P1),Round2(P2)...,Roundn(Pn)] sums to the given target value. Here each operation Roundi(pi) could be either Floor(Pi) or Ceil(Pi).

We have to return the string "-1" if the rounded array is impossible to sum to target. Otherwise, return the smallest rounding error, which will be (as a string with three places after the decimal) defined as −

$\displaystyle\sum\limits_{i-1}^n |Round_{i} (???? ) - ????$

So if the input is like [“0.700”, “2.800”, “4.900”], and the target is 8. Use floor or ceil operations to get (0.7 - 0) + (3 - 2.8) + (5 - 4.9) = 0.7 + 0.2 + 0.1 = 1.0

To solve this, we will follow these steps −

  • ret := 0

  • make one priority queue pq for (double and array) type complex data

  • for i in range 0 to size of prices

    • x := double value of prices[i]

    • low := floor of x

    • high := ceiling of x

    • if low is not high

      • diff := (high - x) – (x - low)

      • insert diff into pq

    • target := target – low

    • ret := ret + (x - low)

  • if target > size of pq or target < 0, then return “-1”

  • while target is not 0

    • ret := ret + top of pq, delete from pq

    • d
    • decrease target by 1

  • s := ret as string

  • return substring s by taking number up to three decimal places

Let us see the following implementation to get better understanding −

Example

 Live Demo

#include <bits/stdc++.h>
using namespace std;
struct Comparator{
   bool operator()(double a, double b) {
      return !(a < b);
   }
};
class Solution {
   public:
   string minimizeError(vector<string>& prices, int target) {
      double ret = 0;
      priority_queue < double, vector < double >, Comparator > pq;
      for(int i = 0; i < prices.size(); i++){
         double x = stod(prices[i]);
         double low = floor(x);
         double high = ceil(x);
         if(low != high){
            double diff = ((high - x) - (x - low));
            pq.push(diff);
         }
         target -= low;
         ret += (x - low);
      }
      if(target > pq.size() || target < 0) return "-1";
      while(target--){
         ret += pq.top();
         pq.pop();
      }
      string s = to_string (ret);
      return s.substr (0, s.find_first_of ('.', 0) + 4);
   }
};
main(){
   vector<string> v = {"0.700","2.800","4.900"};
   Solution ob;
   cout << (ob.minimizeError(v, 8));
}

Input

["0.700","2.800","4.900"]
8

Output

"1.000"

Updated on: 30-Apr-2020

244 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements