Cod sursa(job #3305347)

Utilizator Cyb3rBoltSbora Ioan-David Cyb3rBolt Data 31 iulie 2025 21:02:35
Problema Lapte Scor 40
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.27 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin("lapte.in");
ofstream fout("lapte.out");
#define int long long
int n, need;
int prodA[110], prodB[110], ramas[110];
int solA[110], solB[110];
int sol = 1e18, bestSort;

struct Iris {
    int a, b;
    int index;
}v[110];

inline int cmp1(Iris a, Iris b) { return a.a - a.b > b.a - b.b; }
inline int cmp2(Iris a, Iris b) {
    if(a.a == b.a) return a.b < b.b;
    return a.a > b.a;
}
inline int cmp3(Iris a, Iris b) { return a.b * b.a > a.a * b.b; }
inline int cmp4(Iris a, Iris b) { return (a.b - a.a) * b.a * b.b > (b.b - b.a) * a.a * a.b;}
inline int cmp5(Iris a, Iris b) { return a.a * b.b > a.b * b.a; }
inline int cmp6(Iris a, Iris b) { return abs(a.a - a.b) < abs(b.a - b.b); }

inline int check(int x) {
    for(int i=1; i<=n; i++) prodA[i] = prodB[i] = ramas[i] = 0;
    int cntA = 0, cntB = 0;
    for(int i=1; i<=n; i++) {
        prodA[i] = x / v[i].a;
        cntA += prodA[i];
        ramas[i] = x % v[i].a;
    }
    if(cntA < need) return 0;
    for(int i=1; i<=n; i++) {
        prodB[i] = ramas[i] / v[i].b;
        cntB += prodB[i];
        ramas[i] %= v[i].b;
    }
    if(cntB >= need) return 1;
    for(int i=1; i<=n && cntB < need; i++) {
        int schimbMax = (prodA[i] * v[i].a + ramas[i]) / v[i].b;
        if(cntB + schimbMax < need) {
            ramas[i] = (prodA[i] * v[i].a + ramas[i]) % v[i].a;
            cntA -= prodA[i], prodA[i] = 0;
            prodB[i] = schimbMax, cntB += prodB[i];
            prodA[i] = ramas[i] / v[i].a, cntA += prodA[i];
            ramas[i] %= v[i].a;
        }
        else {
            int dif = need - cntB;
            int take = (dif * v[i].b - ramas[i]) / v[i].a;
            if((dif * v[i].b - ramas[i]) % v[i].a != 0) take++;
            prodA[i] -= take, cntA -= take;
            prodB[i] = dif, cntB = need;
            ramas[i] = (dif * v[i].b - ramas[i]) % v[i].a;
            prodA[i] += ramas[i] / v[i].a, cntA += ramas[i] / v[i].a;
            ramas[i] %= v[i].a;
        }
        if(cntA < need) return 0;
    }
    if(cntA < need || cntB < need) return 0;
    return 1;
}

inline void binara(int indexSort) {
    int st = 1, dr = 1e18;
    while(st <= dr) {
        int mid = (st + dr) / 2;
        if(check(mid)) {
            if(mid < sol) sol = mid, bestSort = indexSort;
            dr = mid - 1;
        }
        else st = mid + 1;
    }
}

signed main()
{
    fin >> n >> need;
    for(int i=1; i<=n; i++) {
        fin >> v[i].a >> v[i].b;
        v[i].index = i;
    }
    sort(v+1, v+n+1, cmp1), binara(1);
    sort(v+1, v+n+1, cmp2), binara(2);
    sort(v+1, v+n+1, cmp3), binara(3);
    sort(v+1, v+n+1, cmp4), binara(4);
    sort(v+1, v+n+1, cmp5), binara(5);
    sort(v+1, v+n+1, cmp6), binara(6);
    if(bestSort == 1) sort(v+1, v+n+1, cmp1);
    else if(bestSort == 2) sort(v+1, v+n+1, cmp2);
    else if(bestSort == 3) sort(v+1, v+n+1, cmp3);
    else if(bestSort == 4) sort(v+1, v+n+1, cmp4);
    else if(bestSort == 5) sort(v+1, v+n+1, cmp5);
    fout << sol << '\n';
    check(sol);
    for(int i=1; i<=n; i++) {
        solA[v[i].index] = prodA[i];
        solB[v[i].index] = prodB[i];
    }
    for(int i=1; i<=n; i++) fout << solA[i] << " " << solB[i] << '\n';

    return 0;
}