文章目录
- 活动安排
- 题解
- 代码
- 哈夫曼编码
- 题解
- 代码
- 奇数位丢弃
- 题解
- 代码

活动安排
题目链接
题解
1. 区间贪心 + 排序
2. 如果有重叠部分,每次选择右端点较小的,可以尽可能多的选择区间个数,如果没有重叠部分,选择下一个区间的右端点为基准,重复刚刚的操作
代码
#include <iostream>
#include<algorithm>
using namespace std;const int N = 2e5 + 10;
typedef pair<int,int> PII;
PII a[N];int main()
{int n;cin >> n;for(int i = 0;i < n;i++) cin >> a[i].first >> a[i].second;sort(a,a+n);int ret = 0,r = a[0].second;for(int i = 1;i < n;i++){// 有重叠if(a[i].first < r){r = min(r,a[i].second);}else // 没有重叠{ret++;r = a[i].second;}}// 未记录第一个区间所以加1cout << ret + 1 << '\n';return 0;
}
哈夫曼编码
题目链接
题解
1. 哈夫曼编码,利用字符出现的频次构建一个二叉树,每次选择频次最小的两个数构建二叉树,根据最优二叉树编码
2. 把题目中数出现的频次放入一个小根堆中,每次取两个数相加放入堆中,然后此时也计算最短长度,直到堆中仅剩一个元素时,得到最短长度
代码
#include <iostream>
#include<queue>
using namespace std;const int N = 2e5 + 10;
int a[N];int main()
{// 小根堆priority_queue<long long,vector<long long>,greater<long long>> pq;int n;cin >> n;for(int i = 0;i < n;i++){cin >> a[i];pq.push(a[i]);}long long count = 0;while(pq.size() != 1){long long a = pq.top();pq.pop();long long b = pq.top();pq.pop();count += a;count += b;pq.push(a + b);}cout << count << '\n';return 0;
}
奇数位丢弃
题目链接
题解
1. 找规律
2. 可以看出每次删除的第一个数是2^n - 1,
求2 ^ x - 1 <= n中x的最大值就是最后剩下的数
代码
#include <iostream>
#include<math.h>
using namespace std;int main()
{int n;while(cin >> n){int x = 0;long long ret = 1;while(ret <= n + 1){ret += pow(2,x);x++; }cout << pow(2,x-1) - 1 << '\n';}return 0;
}#include <iostream>
using namespace std;int main()
{int n;while(cin >> n){int ret = 1;while(ret - 1 <= n) ret *= 2;cout << ret / 2 - 1 << '\n';}return 0;
}