Hướng dẫn giải của VO 12 Bài 6 - Trao đổi


Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.

Lưu ý: Các code mẫu dưới đây chỉ mang tính tham khảo và có thể không AC được bài tập này

Code mẫu của flashmt

#include <iostream>
#include <algorithm>
#include <utility>
#include <cstdio>
using namespace std;

int n;
pair <int,int> a[100100];

bool cmp(pair <int,int> i,pair <int,int> j)
{
    return i.first*j.second>j.first*i.second;
}

int ok(double need)
{
    double gold=0,silver=0;
    int i;
    for (i=0;i<n;i++)
        if (gold+1.0*a[i].first<=need) gold+=a[i].first;
        else
        {
            double x=(need-gold)/a[i].first;
            gold+=x*a[i].first;
            silver+=(1.0-x)*a[i].second;
            i++;
            break;
        }
    if (gold<need) return 0;
    for (;i<n;i++) silver+=a[i].second;
    return silver>=need;
}

int main()
{
    cin >> n;
    for (int i=0;i<n;i++) scanf("%d%d",&a[i].first,&a[i].second);
    sort(a,a+n,cmp);
    double low=0,high=1e8;
    while (high-low>1e-8)
    {
        double mid=(low+high)/2;
        if (ok(mid)) low=mid;
        else high=mid;
    }
    printf("%.8lf\n",(low+high)/2);
}

Code mẫu của happyboy99x

#include<algorithm>
#include<iostream>
#include<iomanip>
#include<vector>
using namespace std;

bool MetalCompare(const pair<int, int> &a, const pair<int, int> &b) {
    return a.first * b.second < b.first * a.second;
}

double getMulCoef(const pair<int, int> &a) {
    return a.first / (double) (a.first + a.second);
}

int main() {
    ios::sync_with_stdio(false);
    int n; cin >> n;
    vector<pair<int, int> > v (n);
    int partA = 0, partB = 0;
    for(int i = 0; i < n; ++i) {
        cin >> v[i].first >> v[i].second;
        partA += v[i].first;
    }
    sort(v.begin(), v.end(), MetalCompare);
    for(int i = 0; i < n; ++i) {
        if(partA - partB > v[i].first + v[i].second) {
            partA -= v[i].first;
            partB += v[i].second;
        } else {
            cout << fixed << setprecision(12) << partA - (partA - partB) * getMulCoef(v[i]) << '\n';
            return 0;
        }
    }
    return 0;
}

Code mẫu của ladpro98

#include <bits/stdc++.h>

using namespace std;
static struct IO {
    char tmp[1 << 10];

    // fast input routines
    char cur;

//#define nextChar() (cur = getc_unlocked(stdin))
//#define peekChar() (cur)
    inline char nextChar() { return cur = getc_unlocked(stdin); }
    inline char peekChar() { return cur; }

    inline operator bool() { return peekChar(); }
    inline static bool isBlank(char c) { return (c < '-' && c); }
    inline bool skipBlanks() { while (isBlank(nextChar())); return peekChar() != 0; }

    inline IO& operator >> (char & c) { c = nextChar(); return *this; }

    inline IO& operator >> (char * buf) {
        if (skipBlanks()) {
            if (peekChar()) {
                *(buf++) = peekChar();
                while (!isBlank(nextChar())) *(buf++) = peekChar();
            } *(buf++) = 0; } return *this; }

    inline IO& operator >> (string & s) {
        if (skipBlanks()) { s.clear(); s += peekChar();
            while (!isBlank(nextChar())) s += peekChar(); }
        return *this; }

    inline IO& operator >> (double & d) { if ((*this) >> tmp) sscanf(tmp, "%lf", &d); return *this; }

#define defineInFor(intType) \
    inline IO& operator >>(intType & n) { \
        if (skipBlanks()) { \
            int sign = +1; \
            if (peekChar() == '-') { \
                sign = -1; \
                n = nextChar() - '0'; \
            } else \
                n = peekChar() - '0'; \
            while (!isBlank(nextChar())) { \
                n += n + (n << 3) + peekChar() - 48; \
            } \
            n *= sign; \
        } \
        return *this; \
    }

defineInFor(int)
defineInFor(unsigned int)
defineInFor(long long)

    // fast output routines

//#define putChar(c) putc_unlocked((c), stdout)
    inline void putChar(char c) { putc_unlocked(c, stdout); }
    inline IO& operator << (char c) { putChar(c); return *this; }
    inline IO& operator << (const char * s) { while (*s) putChar(*s++); return *this; }

    inline IO& operator << (const string & s) { for (int i = 0; i < (int)s.size(); ++i) putChar(s[i]); return *this; }

    char * toString(double d) { sprintf(tmp, "%lf%c", d, '\0'); return tmp; }
    inline IO& operator << (double d) { return (*this) << toString(d); }


#define defineOutFor(intType) \
    inline char * toString(intType n) { \
        char * p = (tmp + 30); \
        if (n) { \
            bool isNeg = 0; \
            if (n < 0) isNeg = 1, n = -n; \
            while (n) \
                *--p = (n % 10) + '0', n /= 10; \
            if (isNeg) *--p = '-'; \
        } else *--p = '0'; \
        return p; \
    } \
    inline IO& operator << (intType n) { return (*this) << toString(n); }

defineOutFor(int)
defineOutFor(long long)

#define endl ('\n')
#define cout __io__
#define cin __io__
} __io__;
const int N = 1e5 + 5;

struct Fraction {
    int numer, denom;
    bool operator < (const Fraction &o) const {
        return numer * o.denom > denom * o.numer;
    }
} a[N];

int main() {
    int n; cin >> n;
    for (int i = 1; i <= n; ++i) cin >> a[i].numer >> a[i].denom;
    double x = 0, y = 0;
    int m = 0;
    for (int i = 1; i <= n; ++i) {
        if (a[i].numer > a[i].denom)
            x += a[i].numer;
        else
            y += a[i].denom;
        if (a[i].numer != 0 &&  a[i].denom != 0) {
            a[++m] = a[i];
        }
    }
    n = m;
    bool swapped = false;
    if (x > y) {
        swapped = true;
        swap(x, y);
        for (int i = 1; i <= n; ++i)
            swap(a[i].numer, a[i].denom);
    }
    sort(a + 1, a + 1 + n);
    for (int i = 1; i <= n; ++i) if (a[i].numer <= a[i].denom - swapped) {
        if (x + a[i].numer <= y - a[i].denom) {
            x += a[i].numer; y -= a[i].denom;
        } else {
            double p = (y - x) / (a[i].denom + a[i].numer);
            x += a[i].numer * p;
            y -= a[i].denom * p;
            break;
        }
    }
    printf("%.6f", min(x, y));
    return 0;
}

Code mẫu của RR

#include <sstream>
#include <iomanip>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <string>
#include <deque>
#include <complex>

#define FOR(i,a,b) for(int i=(a),_b=(b); i<=_b; i++)
#define FORD(i,a,b) for(int i=(a),_b=(b); i>=_b; i--)
#define REP(i,a) for(int i=0,_a=(a); i<_a; i++)
#define FORN(i,a,b) for(int i=(a),_b=(b);i<_b;i++)
#define DOWN(i,a,b) for(int i=a,_b=(b);i>=_b;i--)
#define SET(a,v) memset(a,v,sizeof(a))
#define sqr(x) ((x)*(x))
#define ll long long
#define F first
#define S second
#define PB push_back
#define MP make_pair

#define DEBUG(x) cout << #x << " = "; cout << x << endl;
#define PR(a,n) cout << #a << " = "; FOR(_,1,n) cout << a[_] << ' '; cout << endl;
#define PR0(a,n) cout << #a << " = "; REP(_,n) cout << a[_] << ' '; cout << endl;
using namespace std;

//Buffer reading
int INP,AM,REACHEOF;
#define BUFSIZE (1<<12)
char BUF[BUFSIZE+1], *inp=BUF;
#define GETCHAR(INP) { \
    if(!*inp) { \
        if (REACHEOF) return 0;\
        memset(BUF,0,sizeof BUF);\
        int inpzzz = fread(BUF,1,BUFSIZE,stdin);\
        if (inpzzz != BUFSIZE) REACHEOF = true;\
        inp=BUF; \
    } \
    INP=*inp++; \
}
#define DIG(a) (((a)>='0')&&((a)<='9'))
#define GN(j) { \
    AM=0;\
    GETCHAR(INP); while(!DIG(INP) && INP!='-') GETCHAR(INP);\
    if (INP=='-') {AM=1;GETCHAR(INP);} \
    j=INP-'0'; GETCHAR(INP); \
    while(DIG(INP)){j=10*j+(INP-'0');GETCHAR(INP);} \
    if (AM) j=-j;\
}
//End of buffer reading

const long double PI = acos((long double) -1.0);
const int MN = 100111;

struct Piece {
    int a, b;
    double gold;
} x[MN];

bool operator < (const Piece &a, const Piece &b) {
    return a.gold > b.gold;
}

int n;
int gold[MN], silver[MN];

int main() {
    GN(n);
    FOR(i,1,n) {
        int a, b; GN(a); GN(b);
        x[i].a = a; x[i].b = b;
        x[i].gold = a / (double) (a+b);
    }
    sort(x+1, x+n+1);

    FOR(i,1,n) gold[i] = gold[i-1] + x[i].a;
    FORD(i,n,1) silver[i] = silver[i+1] + x[i].b;

    double res = 0;

    FOR(i,1,n-1) {
        res = max(res, (double)min(gold[i], silver[i+1]));
    }

    FOR(i,0,n-1) {
        double l = 0, r = 1, x1, x2, y1, y2;
        REP(turn,50) {
            x1 = (2*l + r) / 3;
            x2 = (l + 2*r) / 3;
            y1 = min(gold[i] + x1*x[i+1].a, silver[i+2] + (1-x1)*x[i+1].b);
            y2 = min(gold[i] + x2*x[i+1].a, silver[i+2] + (1-x2)*x[i+1].b);

            if (y1 < y2) {
                res = max(res, y2);
                l = x1;
            }
            else {
                res = max(res, y1);
                r = x2;
            }
        }
    }

    printf("%.6lf\n", res);
    return 0;
}

Code mẫu của hieult

#include<cstdio>
#include<cmath>
#include<math.h>
#include<cstring>
#include<cstdlib>
#include<cassert>
#include<ctime>
#include<algorithm>
#include<iterator>
#include<iostream>
#include<cctype>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<list>
#define ep 0.0000001
#define maxn 100001
#define oo 2000000001
#define modunlo 111539786
#define TR(c, it) for(typeof((c).begin()) it=(c).begin(); it!=(c).end(); it++)
#define fi first
#define se second
//#define g 9.81
double const PI=4*atan(1.0);
//#include <conio.h>

using namespace std;

typedef pair<int, int> II;
typedef vector<int> VI;
typedef vector<II> VII;
typedef vector<VI> VVI;
typedef vector<VII> VVII;

struct daquy{
    int vang,bac;
    daquy(){};
    daquy(int _vang, int _bac){
        vang = _vang;
        bac = _bac;
    }
    bool operator <(const daquy &D) const{
        return (long long)bac * D.vang > (long long)D.bac * vang;
    }
};

daquy A[maxn + 5];
int n,a,b;
double tong = 0;

bool check(double x){
    double t = tong - x , res = 0;
    for(int i = 0; i < n; i++){
        if(t >= A[i].vang){
            t -= A[i].vang;
            res += A[i].bac;
        }
        else{
            res += A[i].bac * t / A[i].vang;
            break;
        }
    }

    return res > x;
}

int main(){
  //  freopen("input.in","r",stdin);
  //  freopen("output.out","w",stdout);
    scanf("%d",&n);
    for(int i = 0; i < n; i++){
        scanf("%d %d",&a,&b);
        tong += a;
        A[i] = daquy(a,b);
    }
    sort(A,A+n);
    double u = 0, v = tong, r;
    while(v - u > ep){
        r = (u + v)/2;
        if(check(r)) u = r;
        else v = r;
    }
    printf("%.9lf",u);
}

Code mẫu của ll931110

#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

struct coin {
    int gold,silver;
    double c;
};

bool cmp(coin A,coin B) {
    return A.c > B.c;
}

int k,n;
coin a[100010];

bool ok(double needGold,double needSilver,coin rem) {
    if (needGold > rem.gold) return false;
    if (needSilver > rem.silver) return false;
    return needGold * rem.silver + needSilver * rem.gold <= rem.gold * rem.silver;
}

double maxCut(long long gold,long long silver,coin rem) {
    double low = min(gold,silver),high = 1e9 * n;
    for (int iter = 0; iter < 200; iter++) {
        double mid = (low + high)/2;
        double needGold = max(0.0,mid - gold);
        double needSilver = max(0.0,mid - silver);
        if (ok(needGold,needSilver,rem)) low = mid; else high = mid;
    }
    return low;
}

int main() {
    scanf("%d", &k);
    for (int i = 0; i < k; i++) {
        int x,y;
        scanf("%d %d", &x, &y);
        if (x + y) {
            a[n].gold = x;
            a[n].silver = y;
            a[n].c = (y) ? 1.0 * x/y : 1e10;
            n++;
        }
    }
    sort(a,a + n,cmp);
    long long sumGold = 0,sumSilver = 0;
    for (int i = 0; i < n; i++) sumSilver += a[i].silver;
    double ret = 0;
    for (int i = 0; i < n; i++) {
        if (i) sumGold += a[i - 1].gold;
        sumSilver -= a[i].silver;
        ret = max(ret,maxCut(sumGold,sumSilver,a[i]));
    }
    printf("%.6lf\n", ret);
}

Bình luận

Hãy đọc nội quy trước khi bình luận.


Không có bình luận tại thời điểm này.