the minimum value of |A - a| + |B - b| + |C - c|

Problem Statement

 Krolik found a sheet of paper with an equation containing three positive integers: "a *b =c". This equation might be wrong, so Krolik is trying to make it correct by adjusting the numbersa,b, and c.

You are given three ints a, b, and c. Return a long long containing the minimum value of |A -a| + |B -b| + |C - c|, where A, B, and C arepositive integers satisfying A * B = C.

Definition

 
Class:CorrectMultiplication
Method:getMinimum
Parameters:int, int, int
Returns:long long
Method signature:long long getMinimum(int a, int b, int c)
(be sure your method is public)
 
 

Notes

-|x| is the absolute value of x (which is x for non-negative x and (-x) for negative x).

Constraints

-a, b, and c will each be between 1 and 1,000,000,000, inclusive.

Examples

0) 
 
19
28
522
Returns: 2
By assigning A = 18, B = 29, and C = 522 the value of |A - a| + |B - b| + |C - c| is minimized.
1) 
 
10
30
500
Returns: 11
 
2) 
 
11111
11111
123454321
Returns: 0
 
3) 
 
1000
100
10
Returns: 1089
Note that A, B, and C must be positive integers.
4) 
 
399
522
199999
Returns: 24

(转)http://apps.topcoder.com/wiki/display/tc/SRM+522


long long getMinimum(int a, int b, int c)
{
    // upper bound for the result:
    long long res = a + b + (long long)c - 3
    //note that res can overflow a 32 bits integer.
    
    // C is at most (c + res).

    // #Try a fixed value of A.    
    // A*A is at most (c + res), or A is at most (c+res)/A (to avoid overflow).
    for (int A = 1; A <= (c + res)/A; A ++) {
        // B is equal to c/A-1, c/A, or c/A +1
        for (int o=-1; o<=1; o++) {
            long long B = c/A + o;
            if (B >= 1) {
                long long C = A * B;
                // Verify the cost of the found values, is it the minimum
                // we have found so far? Update it.
                res = std::min(res, abs(A-a) + abs(B-b) + abs(C-c) );

            }
        }
    }

    // #Try a fixed value of B.    
    // B*B is at most (c + res), or B is at most (c+res)/B (to avoid overflow).
    for (int B = 1; B <= (c + res)/B; B ++) {
        // A is equal to c/B-1, c/B, or c/B+1
        for (int o=-1; o<=1; o++) {
            long long A = c/B + o;
            if (A >= 1) {
                long long C = A * B;
                // Verify the cost of the found values, is it the minimum
                // we have found so far? Update it.
                res = std::min(res, abs(A-a) + abs(B-b) + abs(C-c) );

            }
        }
    }
    // there are ways to implement the algorithm without so much repetition,
    // For example, we can just repeat the same code again but after swapping a and b.


    // Return the minimum value we have found.
    return res;
}

//极值确定A,B,C<=res+c ;然后优化
//枚举A, C cannot be larger than (c + A) and cannot be smaller than (c - A)
//最优为|A-a|+|B1-b|+|C1-c| < |A-a|+|B1+x-b|+|C1-x*A-c|
//A*B=C 
#include<stdio.h>
#include<string.h>
typedef long long lld;

class CorrectMultiplication{
public:
	lld min(lld x,lld y){
		if(x<y)return x;
		return y;
	}
	lld abs(lld x){
		if(x<0)return -x;
		return x;
	}
	lld getMinimum(int a, int b, int c)
	{
		lld res=a+b+(lld)c-3;
		lld o;
		lld A,B,C;
		for(A=1;A*A<=res+c;A++)
		{
			for(o=-1;o<=1;o++)
			{
				B=c/A+o;
				if(B>=1)
				res=min(res,abs(A-a)+abs(B-b)+abs(A*B-c));
			}
		}
		for(B=1;B*B<=res+c;B++)
		{
			for(o=-1;o<=1;o++)
			{
				A=c/B+o;
				if(A>=1)
				res=min(res,abs(A-a)+abs(B-b)+abs(A*B-c));
			}
		}
		return res;
	}
};







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值