Translate

Views

Thursday, August 17, 2023

Solution UVA: 10090 - Marbles


  Problem  VerdictLangTimeBestRankSubmit Time
 | discuss10090 - Marbles AcceptedC++110.0100.00013521 mins ago

Suggest: (from codeantenna.com/a/WO2VpJHAQP)
/****************************************************************************
 *
 * let d = gcd (n1, n2)
 *     n1 * x + n2 * y = n  <==>  n1 / d * x + n2 / d * y = n / d  ... (1)
 * let n1 / d * x0 + n2 / d * y0 = 1  ... (2)
 *     x0 and y0 can be get by 'Extended Euclid Algorithm'.
 * multiply (2) by 'n / d' and compare to (1), we get:
 *     x = x0 * n / d
 *     y = y0 * n / d
 * if we have x, y such that:
 *     n1 * x + n2 * y = n
 * then we have:
 *     n1 * (x + i * n2 / d) + n2 * (y - i * n1 / d) = n   (i = 1, 2, ...)  ... (3)
 * because 'n1 * (x + i * n2 / d)' increase n1 * n2 / d while 'n2 * (y - i * n1 / d)' decrease n1 * n2 / d.
 * and here 'x' and 'y' are fixed values.
 *
 * according to the statement of the problem, x >= 0 and y >= 0.
 * so we get:
 *     x + i * n2 / d >= 0 and y - i * n1 / d >= 0
 * solve these two inequations we get the range of 'i', let's note the range [l, u]
 *
 * the problem asks us to minimize 'c1 * x + c2 * y',
 * let z = c1 * (x + i * n2 / d) + c2 * (y - i * n1 / d)  ... (4)
 * so (4) is what we want to minimize.
 * since it's monotonically either increasing or decreasing, what we need to do is examine two cases when i == l and i == u.
 *
 ****************************************************************************/

I was able to solve this problem thanks to the hint provided, although it took some time dealing with the equation 
n1 * (x + i * n2 / d) + n2 * (y - i * n1 / d) = n (i = 1, 2, ...)
<=> n1*x + n2*y + n1*n2/d - n2*n1/d = n
<=> n1*x + n2*y + 0 = n


#include<bits/stdc++.h>
#define int long long
#define X first
#define Y second
using namespace std;

typedef pair<int, int> ii;

int euclid(int a, int b){
    if (b==0) return a;
    return euclid(b, a%b);
}

ii extended_euclid(int a, int b, ii aa, ii bb){
    if (b==0) return aa;

    int div= a/b;
    ii cc(aa.X - div * bb.X, aa.Y - div * bb.Y);

    return extended_euclid(b, a%b, bb, cc);
}

int32_t main(){
    ios::sync_with_stdio(0); cin.tie(0);
    int a, b, c, ca, cb;
   
    while(cin >> c && c){
        cin >> ca >> a >> cb >> b;

        int d= euclid(a, b);
        if (c%d) cout<<"failed\n";
        else{
                ii p= extended_euclid(a, b, ii(1, 0), ii(0, 1));      
                int q= c/d;
                int x= p.X*q;
                int y= p.Y*q;
               
                //x + i * b / d >= 0 and y - i * a / d >= 0
                int l= ceil(-x * d * 1.0/b);
                int r= floor(y * d * 1.0/a);
               
                int x1= x + l * b/d;
                int y1= y - l * a/d;
                int x2= x + r * b/d;
                int y2= y - r * a/d;
                if (x1*ca + y1*cb < x2*ca + y2*cb){
                        if (x1<0 || y1<0) cout<<"failed\n";
                        else cout<<x1<<" "<<y1<<"\n";
                }
                else    
                        if (x2<0 || y2<0) cout<<"failed\n";
                        else cout<<x2<<" "<<y2<<"\n";
       
        }
    }
}

 

ma so sv - ho ten sinh vien.docx - Google Drive

No comments: