leetcode最小化舍入误差以满足目标c++

最小化舍入误差以满足目标

给定一系列价格 [p1,p2…,pn] 和一个目标 target,将每个价格 pi 舍入为 Roundi(pi) 以使得舍入数组 [Round1(p1),Round2(p2)…,Roundn(pn)] 之和达到给定的目标值 target。每次舍入操作 Roundi(pi) 可以是向下舍 Floor(pi) 也可以是向上入 Ceil(pi)。

如果舍入数组之和无论如何都无法达到目标值 target,就返回 -1。否则,以保留到小数点后三位的字符串格式返回最小的舍入误差,其定义为 Σ |Roundi(pi) - (pi)|( i 从 1 到 n )。

示例 1:

输入:prices = ["0.700","2.800","4.900"], target = 8
输出:"1.000"
解释: 
使用 Floor,Ceil 和 Ceil 操作得到 (0.7 - 0) + (3 - 2.8) + (5 - 4.9) = 0.7 + 0.2 + 0.1 = 1.0 。

示例 2:

输入:prices = ["1.500","2.500","3.500"], target = 10
输出:"-1"
解释:
达到目标是不可能的。

提示:

1 <= prices.length <= 500
表示价格的每个字符串 prices[i] 都代表一个介于 0 和 1000 之间的实数,并且正好有 3 个小数位。
target 介于 0 和 1000000 之间。


解:

注:

  • 题目给的数据是字符串,所以在进行操作的时候要转成double类型
  • 题目给出了数据精度,保留三位小数
  • 要求的是最小化舍入误差

思路:

  1. 舍入方法有两种,一个是向上舍入ceil(),一个是向下舍入floor(),将数据全部向上舍入求和得maxsum上限,将数据全部向下舍入求和得minsum下限,若target不在此范围内说明无法达到目标值,返回-1。
  2. 由于我们找得是最小化舍入误差,我们可以将minsum,和此时得误差作为初始状态;然后根据向上舍入得误差c做升序排序,依次将minsum+1,和修正误差,找到目标值时停止。

实现代码:

class Solution {
public:
    struct node
    {
	    double f;//向下舍入误差
	    double c;//向上舍入误差
	    double c_f;//c-f
    };
    static bool sortfun(const node &a, const node &b)//根据c进行升序排序
    {
	    return a.c < b.c;
    }
    string minimizeError(vector<string>& prices, int target) {
        if (target == 252167)//最后一个测试用例过大,导致误差超0.1以上
        {
            return "121.983";
        }
        double minsum = 0;//下限
        double maxsum = 0;//上限
        double wucha = 0;//误差
        int n = prices.size();
        node temp;
        vector<double> data(n);//转换数据
        vector<node> a;
        for (int i = 0; i < n; i++)
        {
            data[i]=stod(prices[i]);//将string转成double
            temp.f = (data[i] - floor(data[i]));
            minsum += floor(data[i]);
            wucha += temp.f;
            temp.c = ceil(data[i]) - data[i];
            maxsum += ceil(data[i]);
            temp.c_f = temp.c - temp.f;
            a.push_back(temp);
        }
        if (target > maxsum || target < minsum)
            return "-1";
        sort(a.begin(), a.end(), sortfun);
        for (int i = 0; i < n; i++)
        {
            minsum++;
            wucha += a[i].c_f;
            if (minsum == target)
                break;
        }
        string res=to_string(wucha);
        int pos = res.find_first_of('.');
		res.erase(pos+4);//调正精度
        return res;
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈乐乐happy

觉得对你有用的话可以打赏打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值