HNAU nine Training Problem 专题三: 数据结构专题 (并查集、堆) 2013 /09 /17 AM 考查知识点 题号 problem_name 具体方法 A. 优先队列 hdu 1434 幸福列车 B. 并查集 poj 1988 C.树状数组 poj 2352 Stars 树状数组入门 D. 堆 poj 2051 Argus 最小堆 E.二维RMQ hdu 2888 Check Corners (数据结构_二维RMQ) F.平衡二叉树poj 3481 Double QUEUE G.堆+模拟 hdu 1103 H.哈希表 poj 3349 雪花 (最简单的哈希表) |
A.幸福列车
#include <cstdio>
#include <queue>
#include <string>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
#define M 10002
struct people{
string name;
int rp;
people(){}
people(string name,int rp)
{
this->name=name;
this->rp=rp;
}
bool operator <(const people &b)const{
return rp!=b.rp?(rp>b.rp):(name<b.name);
}
}p;
int m,n;
priority_queue<people> Q[M];
void init()
{
for(int i=1;i<=n;i++)
{
while(!Q[i].empty())
{
Q[i].pop();
}
}
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("o.txt","w",stdout);
int i,j,k;
char name[100],str[20];
int rp;
int xi,xj;
while(~scanf("%d%d",&n,&m))
{
init();
for(i=1;i<=n;i++)
{
scanf("%d",&k);
for(j=0;j<k;j++)
{
scanf("%s%d",name,&rp);
Q[i].push(people(name,rp));
}
}
//m次操作
for(i=0;i<m;i++)
{
scanf("%s",str);
//合并两车
if(str[0]=='J')
{
scanf("%d%d",&xi,&xj);
people t;
while(!Q[xj].empty())
{
t=Q[xj].top();
Q[xj].pop();
Q[xi].push(t);
}
}
else if(str[4]=='N')
{
scanf("%d%s%d",&xi,name,&rp);
Q[xi].push(people(name,rp));
}
else
{
scanf("%d",&xi);
// if(!Q[xi].empty())
string s=Q[xi].top().name;
Q[xi].pop();
printf("%s\n",s.c_str());
}
}
}
return 0;
}
C.树状数组(入门题)
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define M 15002
#define N 32002
int level[M]; //下标为等级数
int tree[N]; //下标为横坐标
int n;
int lowbit(int x)
{
return x&(-x);
}
void update(int x)
{
for(int i=x;i<N;i+=lowbit(i))
tree[i]+=1;
}
int getsum(int x)
{
int i,sum=0;
for(i=x;i>=1;i-=lowbit(i))
sum+=tree[i];
return sum;
}
int main()
{
int i,x,y;
while(~scanf("%d",&n))
{
memset(level,0,sizeof(level));
memset(tree,0,sizeof(tree));
for(i=0;i<n;i++)
{
scanf("%d%d",&x,&y);
x++;//向右平移,因为x>=0
level[getsum(x)]++;
update(x);
}
for(i=0;i<n;i++)
printf("%d\n",level[i]);
}
return 0;
}
D.Argus
这个晦涩的题目读了好几遍!,才懂
题意: 一个检测系统,可以设置很多个监控进程,一个进程每隔一定period返回一个检测结果,然后将所有进程的这些监测结果按照时间排序输出,如果返回结果的时间相同,那么按照id排序。输出前K个结果的id 即可。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <set>
using namespace std;
#define FLOOR 1002
struct reg{
int id;
int period;
int next;
reg(){}
reg(int id,int p){
this->id=id;
this->next=this->period=p;
}
bool operator <(const reg &b)const{
return next!=b.next?(next<b.next):(id<b.id);
}
};
set<reg> s;
int main()
{
char str[20];
int id,p,q;
s.clear();
while(~scanf("%s",str))
{
if(str[0]=='#')
break;
scanf("%d%d",&id,&p);
s.insert(reg(id,p));
}
scanf("%d",&q);
set<reg>::iterator it;
reg temp;
for(int i=1;i<=q;i++)
{
it=s.begin();
printf("%d\n",(*it).id);
temp=*it;
s.erase(it);
temp.next+=temp.period;
s.insert(temp);
}
return 0;
}