ACM寒假集训第三次专题任务
ACM寒假集训第三次专题任务
一、Priority Queue
题目:

解题思路:
对优先队列的直接运用,直接翻译题目即可。
AC代码:
#include<iostream>
#include<string>
#include<queue>
using namespace std;
int main()
{
int k;
string operation;
priority_queue<int> S;
while(1)
{
cin>>operation;
if(operation=="insert")
{
cin>>k;
S.push(k);
}
else if(operation=="extract")
{
if(!S.empty())
{
cout<<S.top()<<endl;
S.pop();
}
}
else if(operation=="end")
{
break;
}
}
return 0;
}
二、ST 表 && RMQ 问题
题目:


解题思路:
先构建ST表(以Sample 1为例):
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
|---|---|---|---|---|---|---|---|---|
| i=0 | 9 | 3 | 1 | 7 | 5 | 6 | 0 | 8 |
| i=1 | 9 | 3 | 7 | 7 | 6 | 6 | 8 | |
| i=2 | 9 | 7 | 7 | 7 | 8 | |||
| i=3 | 9 |
再输入l和r,判断l到r整个区间的长度,取对数得到小于此长度的最大i(2的i次方,例如,9对应i为3,因为2的3次方为8,而8是小于9的。当i取4时则得到16大于9,不合题意)。
然后判断第一段、第二段起末位置并比较大小。
AC代码:
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
using namespace std;
int N,M,l,r,a[31][100005],len;
int main()
{
scanf("%d%d",&N,&M);
for(int i=1;i<=N;i++)
{
scanf("%d",&a[0][i]);
}
len=log2(N);
for(int i=1;i<=len;i++)
{
for(int j=1;j<=N-(1<<(i-1));j++)
{
a[i][j]=max(a[i-1][j],a[i-1][j+(1<<(i-1))]);
}
}
while(M--)
{
scanf("%d%d",&l,&r);
len=log2(r-l+1);
printf("%d\n",max(a[len][l],a[len][r-(1<<len)+1]));
}
return 0;
}
三、合并果子
题目:


解题思路:
论小根堆的运用,只要把每轮最小的两个加起来并都予去除,再push两者之和进堆即可。
AC代码:
#include<iostream>
#include<queue>
#include<functional>
#include<vector>
using namespace std;
int n,sum,t,k;
priority_queue<int,vector<int>,greater<int>> a;
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
cin>>k;
a.push(k);
}
while(a.size()!=1)
{
t=0;
t+=a.top();
a.pop();
t+=a.top();
sum+=t;
a.pop();
a.push(t);
}
cout<<sum;
}
四、约瑟夫问题
题目:

解题思路:
论队列的运用,把跳过的人从队首调到对尾,出圈的人则输出并从队伍中删除。
AC代码:
#include<iostream>
#include<queue>
using namespace std;
int n,m;
queue<int> a;
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
a.push(i);
}
while(!a.empty())
{
for(int i=1;i<m;i++)
{
int t=a.front();
a.pop();
a.push(t);
}
cout<<a.front()<<" ";
a.pop();
}
return 0;
}
五、Look Up S
题目:


解题思路:
单调栈的运用,相当于一次遍历找所有数的下一最近的大于此数的数的位置。
先把第一个数放进栈,第二个数若比它大,则其为第一个数对应所求;若比它小,则不是,并将第二个数也放进栈。如果第三个数大于第一个数,那么它既为第一个数对应答案也是第二个数对应答案,则将第一个数与第二个数从栈中消去(因为已经找到它们的答案了)。以以上思路进行循环即可得答案。
循环结束后仍在栈中的数则没有对应答案,输出0。
AC代码:
#include<iostream>
#include<vector>
#include<stack>
using namespace std;
struct cow{
int h;
int code;
};
int main()
{
int n;
cin>>n;
vector<int> v(n+1),ans(n+1,0);
stack<cow> s;
for(int i=1;i<=n;i++)
{
cin>>v[i];
}
for(int i=1;i<=n;i++)
{
if(s.empty()||v[i]<=s.top().h)
{
s.push(cow{v[i],i});
}
else
{
while(!s.empty()&&v[i]>s.top().h)
{
ans[s.top().code]=i;
s.pop();
}
s.push(cow{v[i],i});
}
}
while(!s.empty())
{
ans[s.top().code]=0;
s.pop();
}
for(int i=1;i<=n;i++)
{
cout<<ans[i]<<endl;
}
return 0;
}
六、国旗计划
题目:


解题思路:
环的问题,2倍链处理。结构体输入战士信息。假设对i战士进行分析,其右端点为r[i],那么下一个战士j要符合条件:
-
l[j]≤r[i],保证能够覆盖要求
-
r[j]尽量大,这是为了能够最优
用ST表进行处理
AC代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN = 2e5 + 5;
int n, m;
int ans[MAXN];
int f[MAXN*2][20];
struct node {
int id;
int l, r;
} s[MAXN*2];
bool cmp(node a, node b) {
return a.l < b.l;
}
void pre() {
for (int i = 1, p = i; i <= 2 * n; i++) {
while (p <= 2 * n && s[p].l <= s[i].r) {
p++;
}
f[i][0] = p - 1;
}
for(int i = 1; i < 20; i++) {
for(int j = 1; j <= 2 * n; j++) {
f[j][i] = f[f[j][i-1]][i-1];
}
}
}
void solve(int k) {
int rr = s[k].l + m;
int tot = 1;
int p = k;
for (int i = 19; i >= 0; i--) {
if (f[k][i] != 0 && s[f[k][i]].r < rr) {
tot += (1 << i);
k = f[k][i];
}
}
ans[s[p].id] = tot + 1;
}
int main(){
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%d %d", &s[i].l, &s[i].r);
if (s[i].r < s[i].l) {
s[i].r += m;
}
s[i].id = i;
}
sort(s + 1, s + 1 + n, cmp);
for(int i = 1; i <= n; i++) {
s[i + n] = s[i];
s[i + n].l = s[i].l + m;
s[i + n].r = s[i].r + m;
}
pre();
for(int i = 1; i <= n; i++) {
solve(i);
}
for(int i = 1; i <= n; i++) {
printf("%d ", ans[i]);
}
return 0;
}
学习总结
学习了一些数据结构
stack
头文件#include <stack>

定义:stack<int> s;
queue
头文件#include <queue>


定义:queue<int> q;
priority_queue
头文件#include <queue>

定义:priority_queue<int> q;默认为大根堆
定义小根堆:priority_queue<int, vector<int>,greater<int> > p;
ST表
详细使用见二、ST 表 && RMQ 问题。

浙公网安备 33010602011771号