《算法竞赛进阶指南》0x07 代码 + 杂谈

贪心

orz 贪心和DP 快差不多一样难了

Sunscreen
直接贪 cow 按 l 升序 r 升序 排 spf 也升序排 这样 每个牛选最前面的尽量不挤还没的cow 就差不多了

#include <bits/stdc++.h>
using namespace std;
const int maxn = 10005;

struct node {
    int l, r;
    bool operator < (const node &a) const {
        return a.l < l || (a.l == l && a.r < r);
    }
} c[maxn];

struct ct {
    int spf, cov;
    bool operator < (const ct &a) const {
        return a.spf < spf;
    }
} d[maxn];


int main() {
    int n, m;
    cin >> n >> m;
    for(int i = 1; i <= n; i ++) {
        cin >> c[i].l >> c[i].r;
    }
    sort(c + 1, c + 1 + n);
    for(int i = 1; i <= m; i ++) {
        cin >> d[i].spf >> d[i].cov;
    }
    sort(d + 1, d + 1 + m);

    int pos = 1;
    int ans = 0;
    for(int i = 1; i <= n; i ++) {
        for(int j = 1; j <= m; j ++ ) {
            if(d[j].spf >= c[i].l && d[j].spf <= c[i].r && d[j].cov) {
                ans ++;
                d[j].cov --;
                break;
            }
        }
    }
    cout << ans << endl;
    return 0;
}

yxc老师写的 nlgn 写法

#include <cstring>
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;

typedef pair<int,int> PII;
const int N = 2510;
int n, m;
PII cows[N];

int main(){
    cin >> n >> m;
    map<int, int> spfs;
    for (int i = 0; i < n; i ++ ) cin >> cows[i].first >> cows[i].second;
    for (int i = 0; i < m; i ++ ){
        int spf, cover;
        cin >> spf >> cover;
        spfs[spf] += cover;
    }
     sort(cows, cows + n, [](PII lhs, PII rhs) {
        if (lhs.second == rhs.second) {
            return lhs.first < rhs.first;
        }

        return lhs.second < rhs.second;
    });
    int res = 0;
    spfs[0] = spfs[1001] = n;
    for (int i = 0; i < n; i ++ )
    {
        auto it = spfs.lower_bound(cows[i].first);
        if (it->first <= cows[i].second)
        {
            res ++ ;
            if (--it->second == 0)
                spfs.erase(it);
        }
    }
    cout << res << endl;
    return 0;
}

畜栏预订
拿队列模拟

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
struct node{
    int s, d, id;
    bool operator < (const node & a) const {
        return d > a.d;
    }
}c[maxn];

bool cmp(node a,node b){
    return a.s < b.s || (a.s == b.s && a.d > b.d);
}

priority_queue<node> que;
int vc[maxn];
signed main(){
    int n;
    cin >> n;
    for(int i = 1; i <= n; i ++ ) {
        cin >> c[i].s >> c[i].d;
        c[i].id = i;
    }
    sort(c + 1, c + 1 + n, cmp);

    int ans = 0;
    int cnt = 1;
    for(int i = 1; i <= n; i ++ ) {
        if(que.empty()){
            que.push(c[i]);
            vc[c[i].id] = ++ ans;
        }else{
            if(que.top().d >= c[i].s){
                vc[c[i].id] = ++ ans;
                que.push(c[i]);
            }else{
                vc[c[i].id] = vc[que.top().id];
                que.pop();
                que.push(c[i]);
            }
        }
    }
    cout << ans << endl;
    for(int i = 1; i <= n; i ++ ) {
        cout << vc[i] << endl;
    }

    return 0;
}

雷达设备
把 图上的点用圆划到x轴 然后不断贪 尽可能右端

#include <bits/stdc++.h>
using namespace std;

const int maxn = 1e5 + 5;
double R;
int flag = 0;
struct node {
    double x, y, l, r;

    node() {}
    node(double _x, double _y) {
        if(y > R)
            flag = 1;
        x = _x, y = _y;
        double s = sqrt(abs(R * R - y * y)) ;
        l = x - s;
        r = x + s;
    }

    bool operator < (const node & a) const {
        return r < a.r || (r == a.r && l < a.l);
    }
} c[maxn];

signed main() {
    int n;
    cin >> n >> R;
    double x, y;
    for(int i = 1; i <= n; i ++) {
        cin >> x >> y;
        c[i] = node(x, y);
    }
    int ans = 0;
    if(flag) {
        cout << -1 << endl;
        return 0;
    } else {
        sort(c + 1, c + 1 + n);
        double r=-1e9;
        for(int i = 1; i <= n; i ++ ) {
            if(c[i].l > r){
                r = c[i].r;
                ans ++;
            }else{
                continue;
            }
        }
    }
    cout << ans << endl;
    return 0;
}

国王的游戏
高精*低精 + 邻项扰动

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
#define A first
#define B second
const int maxn = 1e5 + 5;
const int HEX = 1000;
pair<int, int> p[maxn];
vector<int> res, ans;

bool cmp(pair <int, int> a, pair<int, int> b) {
    return a.A * a.B < b.A * b.B;
}

void mul(vector<int> &a, int b) {
    int t = 0;
    for (int i = 0; i < a.size(); i ++ ) {
        a[i] = a[i] * b + t;
        t = a[i] / HEX;
        a[i] %= HEX ;
    }
    while (t) {
        a.push_back(t % HEX);
        t /= HEX;
    }
}

vector<int> div(vector<int> res, int b) {
    int t = 0;
    for(int i = res.size() - 1; i >= 0; i -- ) {
        res[i] += t * HEX;
        t = res[i] % b;
        res[i] /= b;
    }
    while(res.size() > 1 && res.back() == 0) res.pop_back();
    return res;
}

vector<int> max(vector<int> &a, vector<int> &b) {
    if (a.size() > b.size()) return a;
    if (a.size() < b.size()) return b;
    if (vector<int>(a.rbegin(), a.rend()) > vector<int>(b.rbegin(), b.rend())) return a;
    return b;
}

signed main() {
    int n;
    cin >> n;
    int a1, b1;
    cin >> a1 >> b1;
    for(int i = 1; i <= n; i ++)
        cin >> p[i].first >> p[i].second;
    sort(p + 1, p + 1 + n, cmp);

    while(a1) {
        res.push_back(a1 % HEX);
        a1 /= HEX;
    }
    for(int i = 1; i <= n; i ++) {
        vector<int> tt;
        ans = max( tt = div(res, p[i].B), ans);
        mul(res, p[i].A);
    }
    printf("%d", ans.back());
    for(int i = ans.size() - 2; i >= 0; i --) {
        printf("%03d", ans[i]);
    }
    cout << endl;
    return 0;
}

树染色
好难想+写啊

#include <iostream>
using namespace std;
const int maxn = 1e5 + 5;
const int mod = 1e9 + 7;

struct node {
	int fa, val, siz;
	double avg;
} no[maxn];

int n, R;

int finds() {
	int p = 0;
	double avg = 0;
	for(int i = 1; i <= n; i ++ ) {
		if(i != R && avg < no[i].avg) {
			p = i;
			avg = no[i].avg;
		}
	}
	return p;
}

signed main() {
	while(cin >> n >> R, n != 0 && R != 0) {
		int ans = 0;
		for(int i = 1, v; i <= n; i ++ ) {
			cin >> v;
			no[i].siz = 1;
			no[i].avg = 1.0 * v;
			no[i].val = v;
			ans += v;
		}
		for(int i = 1, a, b; i < n; i ++ ) {
			cin >> a >> b;
			no[b].fa = a;
		}
		for(int i = 1; i < n; i ++ ) {
			int p = finds();
			int fa = no[p].fa;
			ans += no[fa].siz * no[p].val; // 相当于补长他是第几次 * T
			no[p].avg = -1;
			for(int j = 1; j <= n; j ++ ) {
				if(no[j].fa == p)
					no[j].fa = fa;
			}
			no[fa].val += no[p].val;
			no[fa].siz += no[p].siz;
			no[fa].avg = (double)no[fa].val / no[fa].siz;
		}
		cout << ans << endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40831340/article/details/94625592