题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5071
题面:

1 18 Prior Add 1 Chat 1 Add 2 Chat 2 Top 2 Chat 3 Untop Chat 4 Choose 2 Chat 5 Rotate 2 Chat 4 Close 2 Add 3 Prior Chat 2 Close 1
Operation #1: empty. Operation #2: success. Operation #3: success. Operation #4: success. Operation #5: success. Operation #6: success. Operation #7: success. Operation #8: success. Operation #9: success. Operation #10: success. Operation #11: success. Operation #12: success. Operation #13: success. Operation #14: close 2 with 8. Operation #15: success. Operation #16: success. Operation #17: success. Operation #18: close 1 with 11. Bye 3: 2HintThis problem description does not relate to any real person in THU.
解题:
之前一直觉得很烦,没敢写,没想到居然能1A,还是比较惊喜的!
对应8种操作,我采用的数据结构是两个map。第一个map为<(int)pos,(node)n>,其中pos为位置,n为节点,节点中包含两个值u(优先级权值),w(单词数量)。第二个map为<(int)u,(int)pos>其中u为优先级权值,pos为位置,topp存储的是被top的那个对象的优先级,如果为-1,则说明,没有对象处在top状态,sz为当前节点数量。topp和sz都需要时时更新。
1.添加操作,先看是否已经存在(map.count判断),若没有,则添加,否则显示错误信息。
2.关闭操作,看是否存在,若不存在,显示错误信息,否则删除当前节点,并将后面的往上顺移一位。
3.聊天操作,看sz是否为0,若为0,则显示错误信息。若不为0,则看topp是否为-1,若不为-1,则通过map2找到对应位置,更新map1中的值,若为-1,则更新位置为1的map1中的值。
4.置顶操作,首先判断是否越界,不越界则将该位置提到首位即可,其实应该写成函数供下面功能使用,不过好在代码都是差不多的,拷贝下就好了。
5.优先级置顶,循环遍历,然后将该位置置顶,与上同。
6.通过map2找到对应位置,并置顶。
7.将topp值改成此时的u值。
8.将topp还原为-1。
最后要注意还要输出和剩下的没关闭的窗口聊天的数量,若为0,则不需输出,同时要将优先级最高的先输出。
坑点:
1.topp值和sz值需时时维护。
2.数量应用long long保存。
3.输出答案时,最后是有‘.‘的。
4.最后输出窗口要先输出处于top状态的,没有就按顺序即可。
代码:
#include <iostream>
#include <cmath>
#include <cstdio>
#include <map>
#define LL long long
using namespace std;
struct node
{
node (int x,LL y)
{
u=x;
w=y;
}
node ()
{
u=0;
w=0;
}
node (const node &xx)
{
u=xx.u;
w=xx.w;
}
//u优先级权值,w数量
int u;
LL w;
};
map <int,node> store;
map <int,int> refl;
int main()
{
int t,n,val,sz,pos,topp,uu,maxn;
LL amt,ww;
char oper[10];
scanf("%d",&t);
node tmp;
for(int i=1;i<=t;i++)
{
store.clear();
refl.clear();
sz=0;
topp=-1;
scanf("%d",&n);
for(int j=1;j<=n;j++)
{
printf("Operation #%d: ",j);
getchar();
scanf("%s",oper);
//加操作
if(oper[0]=='A')
{
scanf("%d",&val);
if(!refl.count(val))
{
printf("success.\n");
tmp.w=0;
tmp.u=val;
pos=++sz;
refl[val]=pos;
store[pos]=tmp;
}
else
printf("same priority.\n");
}
//关闭操作
else if(oper[0]=='C'&&oper[1]=='l')
{
scanf("%d",&val);
if(!refl.count(val))
printf("invalid priority.\n");
else
{
if(val==topp)
topp=-1;
pos=refl[val];
amt=store[pos].w;
refl.erase(val);
for(int k=pos+1;k<=sz;k++)
{
uu=store[k].u;
store[k-1].u=store[k].u;
store[k-1].w=store[k].w;
refl[uu]=k-1;
}
store.erase(sz);
sz--;
printf("close %d with %d.\n",val,amt);
}
}
//聊天功能
else if(oper[0]=='C'&&oper[2]=='a')
{
scanf("%d",&val);
if(sz==0)
printf("empty.\n");
else
{
printf("success.\n");
if(topp==-1)
store[1].w+=val;
else
{
pos=refl[topp];
store[pos].w+=val;
}
}
}
//置顶操作
else if(oper[0]=='R')
{
scanf("%d",&val);
if(val<1||val>sz)
printf("out of range.\n");
else
{
printf("success.\n");
uu=store[val].u;
ww=store[val].w;
for(int k=val-1;k>=1;k--)
{
store[k+1].u=store[k].u;
store[k+1].w=store[k].w;
refl[store[k+1].u]=k+1;
}
store[1].u=uu;
store[1].w=ww;
refl[uu]=1;
}
}
//优先级置顶
else if(oper[0]=='P')
{
if(sz==0)
printf("empty.\n");
else
{
printf("success.\n");
maxn=0;
for(int k=1;k<=sz;k++)
{
if(store[k].u>maxn)
maxn=store[k].u;
}
val=refl[maxn];
uu=store[val].u;
ww=store[val].w;
for(int k=val-1;k>=1;k--)
{
store[k+1].u=store[k].u;
store[k+1].w=store[k].w;
refl[store[k+1].u]=k+1;
}
store[1].u=uu;
store[1].w=ww;
refl[uu]=1;
}
}
//选择置顶
else if(oper[0]=='C')
{
scanf("%d",&val);
if(!refl.count(val))
printf("invalid priority.\n");
else
{
printf("success.\n");
val=refl[val];
uu=store[val].u;
ww=store[val].w;
for(int k=val-1;k>=1;k--)
{
store[k+1].u=store[k].u;
store[k+1].w=store[k].w;
refl[store[k+1].u]=k+1;
}
store[1].u=uu;
store[1].w=ww;
refl[uu]=1;
}
}
//top操作
else if(oper[0]=='T')
{
scanf("%d",&val);
if(!refl.count(val))
printf("invalid priority.\n");
else
{
printf("success.\n");
topp=val;
}
}
//untop操作
else if(oper[0]=='U')
{
if(topp==-1)
printf("no such person.\n");
else
{
printf("success.\n");
topp=-1;
}
}
}
//特殊优先级优先
if(topp!=-1&&store[refl[topp]].w)
printf("Bye %d: %I64d\n",topp,store[refl[topp]].w);
for(int i=1;i<=sz;i++)
{
//优先级只需输出一次
if(store[i].u!=topp&&store[i].w>0)
printf("Bye %d: %I64d\n",store[i].u,store[i].w);
}
}
return 0;
}版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/david_jett/article/details/47704581