acm寒假集训第三讲总结

1.Priority Queue

思路:
建立优先队列储存和使用数据,再使用strcmp函数识别题目要求的指令

代码:

#include <iostream>
#include <string.h>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
int main()
{
	priority_queue<long long int> q;
	char op[20];
	long long int x;
	cin>>op;
	while(strcmp(op,"end"))
	{
		if(strcmp(op,"insert")==0)
		{
			cin>>x;
			q.push(x);
		}
		else if(strcmp(op,"extract")==0)
		{
			cout<<q.top()<<endl;
			q.pop();
		}
		cin>>op;
	}
	return 0;
}

2.ST 表 && RMQ 问题

思路:
通过建立st表,提前计算出每个数据往后一段区间内的最大值,这样就保证每次查询的复杂度为O(1),解题时通过快速读入,减少在循环中执行的代码,使用printf输出,只使用必要的头文件等方式避免TLE

代码:

#include <cstdio>
#include <cmath>
#include <algorithm>
const int N=5e6; 
int smax[N][31]; 
using namespace std;
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
int main()
{
	int n,m,i,j;
	n=read();m=read();
	for(i=1;i<=n;i++)
	{
		smax[i][0]=read();
	}
	int x=log2(n);
	for(j=1;j<=x;j++)
	{
		for(i=1;i+(1<<j)-1<=n;i++)
		{
			smax[i][j]=max(smax[i][j-1],smax[i+(1<<(j-1))][j-1]); 
		}
	}
	int l,r;
	for(i=0;i<m;i++)
	{
		l=read();r=read();
		int s=log2(r-l+1);
		printf("%d\n",max(smax[l][s],smax[r-(1<<s)+1][s]));
	}
	return 0;
}

3.合并果子

思路:
由题意,只要保证每次合并操作都是最省力的方案,消耗的总体力一定最少,通过建立一个小根堆来模拟这一过程

代码:

#include <bits/stdc++.h>
using namespace std;
int main()
{
	priority_queue<long long int,vector<long long int>,greater<long long int> > p;
	long long int n,i,sum=0;
	cin>>n;
	for(i=0;i<n;i++)
	{
		long long int ls;
		cin>>ls;
		p.push(ls);
	}
	for(i=0;i<n-1;i++)
	{
		long long int w1,w2,tl=0;
		w1=p.top();p.pop();
		w2=p.top();p.pop();
		tl=w1+w2;
		sum+=tl;
		p.push(tl);
	}
	cout<<sum;
	return 0;
}

4.约瑟夫问题

思路:
建立一个环形的链表,不断循环这个链表并让正确的编号出列,直到链表中的所有元素都被标记为出列即可

代码:

#include <bits/stdc++.h>
using namespace std;
struct link
{
	int value,is;
	struct link *next;
	struct link *last;
};
int main()
{
	int n,m,i=1;
	cin>>n>>m;
	struct link *head=(struct link*)malloc(sizeof(struct link));
	struct link *p=NULL;
	p=head;
	head->value=i;head->is=1;head->next=NULL;head->last=NULL;
	for(i=2;i<=n;i++)
	{
		p->next=(struct link*)malloc(sizeof(struct link));
		p->next->value=i;p->next->is=1;p->next->next=NULL;p->next->last=p;
		p=p->next;
	}
	p->next=head;
	head->last=p;
	p=head;
	int cnt_chuquan=0,cnt=0;
	while(cnt_chuquan<n)
	{
		if(p->is==1)
		{
			cnt++;
			if(cnt==m)
			{
				p->is=0;
				cnt=0;
				cnt_chuquan++;
				cout<<p->value<<" ";
			}
		}
		p=p->next;
	}
	return 0;
}

5.Look Up S

思路:
建立一个小根堆,从左到右读入数据,如果堆不为空且读入元素比堆顶的大,说明读入元素是堆顶元素的仰望对象,记录并删除堆顶,继续比较直到堆为空或读入元素比堆顶的小,将读入元素放入堆,进行下一个数据读入

代码:

#include <bits/stdc++.h>
using namespace std;
struct cow
{
	int height,p,yangwang;
};
int main()
{
	stack<cow> s;
	int n,i;
	cin>>n;
	int res[n+5];
	struct cow x;
	for(i=1;i<=n;i++)
	{
		cin>>x.height;
		x.p=i;x.yangwang=0;
		while(1)
		{
			if(s.empty()||x.height<=(s.top()).height)
			{
				s.push(x);
				break;
			}
			else
			{
				(s.top()).yangwang=x.p;
				res[(s.top()).p]=(s.top()).yangwang;
				s.pop();
			}
		}
	}
	while(!(s.empty()))
	{
		res[(s.top()).p]=(s.top()).yangwang;
		s.pop();
	}
	for(i=1;i<=n;i++)
	{
		cout<<res[i]<<endl;
	}
	return 0;
}

学习总结:
通过这次的学习,我学习了堆和栈这两个STL容器的使用以及小根堆的建立方法,还学习了ST表的基本原理和操作方法,ST表是一种通过预处理数据实现O(1)查询的高效方法,在讲解时也了解到了一些高效的代码实现方法。

posted @   asdadsdf  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· Apache Tomcat RCE漏洞复现(CVE-2025-24813)
点击右上角即可分享
微信分享提示