题目链接: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