《算法竞赛进阶指南》0x10二叉堆

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

const int N = 1e5 + 10;
int n, cnt, a[N];

void down(int u) {
	int maxx = u;
	
	if (u * 2 <= cnt && a[u * 2] < a[maxx]) maxx = u * 2;
	if (u * 2 + 1 <= cnt && a[u * 2 + 1] < a[maxx]) maxx = u * 2 + 1;
	
	if (maxx != u) {
		swap(a[maxx], a[u]);
		down(maxx);
	}
}

int main() {
	cin >> n ;
	cnt = n;
	for (int i = 1; i <= n; i ++) cin >> a[i];
	
	for (int i = n / 2; i > 0; i --) down(i);
	
	for (int i = 1; i <= n; i ++) {
		cout << a[1] << ' ';
		swap(a[1], a[cnt --]);
		down(1);
	}

	return 0;
}
谁考了第k名
#include <bits/stdc++.h>
using namespace std;

int n, k;
struct info {
	string s;
	double scr;
}a[105];

void up(int u) {
	if (u == 1) return;
	
	if (a[u].scr > a[u >> 1].scr) {
		swap(a[u], a[u >> 1]);
		up(u >> 1);
	}
}

void down(int u) {
	int maxx = u;
	if ((u << 1) <= n && a[u << 1].scr > a[maxx].scr) maxx = (u << 1);
	if ((u << 1 | 1) <= n && a[u << 1 | 1].scr > a[maxx].scr) maxx = (u << 1 | 1);
	
	if (maxx != u) {
		swap(a[u], a[maxx]);
		down(maxx);
	}
}

int main() {
	cin >> n >> k;
	for (int i = 1; i <= n; i ++) {
		cin >> a[i].s >> a[i].scr;
		up(i);
	}

	for (int i = 1; i < k; i ++) {
		swap(a[1], a[n --]);
		down(1);
	}
	cout << a[1].s << ' ' << a[1].scr << endl;

	return 0;
}
看病
  • 利用pair
#include <bits/stdc++.h>
using namespace std;

int n;
priority_queue < pair<int, string> > q;

int main() {
	cin >> n;
	while (n --) {
		string op, a;
		int b;
		cin >> op;
		if (op == "push") {
			pair<int, string> p;
			cin >> p.second >> p.first;
			q.push(p);
		}
		else {
			if (q.empty()) puts("none");
			else {
				cout << q.top().second << ' ' << q.top().first << endl;
				q.pop();
			}
		}
	}

	return 0;
}
  • 重载小于运算符
#include <bits/stdc++.h>
using namespace std;

int n;
struct info {
	string a;
	int b;
};

//如果返回真,那么结构体 x < y 
bool operator < (info x, info y) {
	return x.b < y.b;
}
priority_queue <info, vector<info>, less<info> > q;

int main() {
	scanf("%d", &n);
	while (n --) {
		string op, a;
		int b;
		cin >> op;
		if (op == "push") {
			string a;
			int b;
			cin >> a >> b;
			q.push({a, b});
		}
		else {
			if (q.empty()) puts("none");
			else {
				cout << q.top().a << ' ' << q.top().b << endl;
				q.pop();
			}
		}
	}

	return 0;
}
有序表的最小和
#include <bits/stdc++.h>
using namespace std;

const int N = 4e5 + 10;
long long n, a[N], b[N];

struct info{
	int i, j;
	long long val;
};

//如果返回真,那么结构体 x > y
bool operator > (info x, info y) {
	return x.val > y.val;
}
priority_queue <info, vector<info>, greater<info> > q;

int main() {
	scanf("%lld", &n);
	for (int i = 1; i <= n; i ++) scanf("%lld", &a[i]);
	for (int i = 1; i <= n; i ++) scanf("%lld", &b[i]);
	
	for (int i = 1; i <= n; i ++) {
		//把a数组的第1个,b数组的第i个放入优先队列
		q.push((info){1, i, a[1] + b[i]});
	}
	
	for (int k = 1; k <= n; k ++) {
		info t = q.top(); 
		q.pop();
		printf("%lld\n", t.val);

		//堆顶元素是a[t.i] + b[t.j],
		//因为:a[t.i] <= a[t.i + 1], 
		//所以:a[t.i] + b[t.j] <= a[t.i + 1] + b[t.j], 
		//所以接下来替代a[t.i] + b[t.j]的应该是 a[t.i + 1] + b[t.j] 
		q.push((info){t.i + 1, t.j, a[t.i + 1] + b[t.j]});
	}
		
	return 0;
}
超市
#include <bits/stdc++.h>
using namespace std;

const int N = 1e4 + 10;
int n;
struct info {
	int p, d;
}a[N];
bool cmp(info x, info y) {
	return x.d < y.d;
}

priority_queue <int, vector<int>, greater<int> > heap;

int main() {
	while (cin >> n) {		
		for (int i = 1; i <= n; i ++) {
			cin >> a[i].p >> a[i].d;
		}
		sort(a + 1, a + 1 + n, cmp);
		
		for (int i = 1; i <= n; i ++) {
			heap.push(a[i].p);
			if (heap.size() > a[i].d) {
				heap.pop();
			}
		}
		
		int ans = 0;
		while (heap.size()) {
			ans += heap.top();
			heap.pop();
		}
		cout << ans << endl;
	}	

	return 0;
}
哈夫曼编码1
#include <bits/stdc++.h>
using namespace std;

const int N = 109;
int n;
struct node {
	char ch, code;
	int w, p, id;
}a[N];
bool operator > (node x, node y) {
	if (x.w > y.w) return true;
	if (x.w == y.w) {
		if (x.ch > y.ch) return true;
	}
	return false;
}
priority_queue <node, vector<node>, greater<node> > q;

int main() {
	while (cin >> n) {
		for (int i = 1; i <= n; i ++) {
			char ch;
			int w;
			cin >> ch >> w;
			a[i] = {ch, ' ', w, -1, i};
			q.push(a[i]);
		}
		
		while (q.size() > 1) {
			node x = q.top(); q.pop();
			node y = q.top(); q.pop();
			
			a[++ n] = {x.ch, ' ', x.w + y.w, -1, n};
			a[x.id].p = n; 
			a[y.id].p = n;
			a[x.id].code = '0'; 
			a[y.id].code = '1';
			q.push(a[n]);
		}
		q.pop();

		n = n / 2 + 1;
		for (int i = 1; i <= n; i ++) {
			string s = "";
			int t = a[i].id;
			while (a[t].p != -1) {
				s = a[t].code + s;
				t = a[t].p;
			}
			cout << a[i].ch << ':' << s << endl;
		}
	}
	
	return 0;
}
哈夫曼编码2
#include <bits/stdc++.h>
using namespace std;

const int N = 109;
int n;
struct node {
	char ch;
	int dep, w, p, id;
}a[N];

priority_queue <node, vector<node>, greater<node> > q;
bool operator > (node x, node y) {
	if (x.w > y.w) return true;
	if (x.w == y.w) {
		if (x.ch > y.ch) return true;
	}
	return false;
}

int main() {
	while (cin >> n && n != 0) {
		for (int i = 1; i <= n; i ++) {
			char ch;
			int w;
			cin >> ch >> w;
			a[i] = (node){ch, 0, w, -1, i};
			q.push(a[i]);
		}
		
		while (q.size() > 1) {
			node x = q.top(); q.pop();
			node y = q.top(); q.pop();
			
			a[++ n] = (node){' ', 0, x.w + y.w, -1, n};
			a[x.id].p = n; 
			a[y.id].p = n;
			q.push(a[n]);
		}
		q.pop();

		int ans = 0;
		n = n / 2 + 1;
		for (int i = 1; i <= n; i ++) {
			int t = a[i].id;
			while (a[t].p != -1) {
				a[i].dep += 1;
				t = a[t].p;
			}
			ans += a[i].w * a[i].dep;
		}
		cout << ans << endl;
	}
	
	return 0;
}
花生采摘
#include <bits/stdc++.h>
using namespace std;

const int N = 30;
int m, n, k, t, cnt;

struct node{
	int x, y, num;
};
bool operator < (node x, node y) {
	return x.num < y.num;
}
priority_queue <node, vector<node>, less<node> > q;

int main() {
	cin >> m >> n >> k;
	for (int i = 1; i <= m; i ++) {
		for (int j = 1; j <= n; j ++) {
			int p;
			cin >> p;
			node t = {i, j, p};			 
			q.push(t);			     		//优先队列堆顶的花生数量最多
		}
	}
	
	node pre, now;
	for (int i = 1; ; i ++) {
		now = q.top();
		if (i == 1) pre = {0, now.y, 0};	//从第0行第now.y列出发 

		t += abs(now.x - pre.x) + abs(now.y - pre.y) + 1;	//曼哈顿距离 + 采摘时间 
		if (t + now.x <= k) cnt += now.num;	//如果来得及回去就采 
		else break;							//否则就回去 
		
		pre = now;
		q.pop();
		
		if (q.empty()) break;				//采完了就回去 
	}
	cout << cnt << endl;

	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值