本文主要是介绍HDU 3031 To Be Or Not To Be,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题意:
n堆数字 m个操作 操作是两个人轮流执行 有5种操作 T操作拿一堆数字 C操作两个人比较自己手中最大的数字胜者得到对方的数字 L操作扔掉最大数字 A操作使最大数字加上一个值 E操作是最大数字改变值 两个人按上述规则进行R轮游戏 问每局游戏的比分和最后谁赢
思路:
要么是合并一堆数字 要么从一堆数字里拿最大 很明显这时可并堆的操作 想到使用左偏树
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 2001000int R,happy,wolf,n,m,tot;
int f[110],root[2],sum[110];
struct node
{int v,l,r,dis;
}nd[N];int newnode(int x)
{nd[tot].v=x;nd[tot].l=0;nd[tot].r=0;nd[tot].dis=0;tot++;return tot-1;
}int merge(int x,int y)
{if(!x) return y;if(!y) return x;if(nd[x].v<nd[y].v) swap(x,y);nd[x].r=merge(nd[x].r,y);if(nd[nd[x].l].dis<nd[nd[x].r].dis) swap(nd[x].l,nd[x].r);nd[x].dis=nd[nd[x].r].dis+1;return x;
}int pop(int x)
{int tmp=merge(nd[x].l,nd[x].r);nd[x].dis=nd[x].l=nd[x].r=0;return tmp;
}int main()
{int i,j,k,num;char op[10];while(~scanf("%d",&R)){happy=wolf=0;while(R--){scanf("%d%d",&n,&m);tot=1;memset(f,0,sizeof(f));memset(sum,0,sizeof(sum));root[0]=root[1]=0;for(i=1;i<=m;i++) scanf("%d",&sum[i]);for(i=1;i<=m;i++){for(j=1;j<=sum[i];j++){scanf("%d",&num);f[i]=merge(f[i],newnode(num));}}for(i=1;i<=n;i++){scanf("%s",op);if(op[0]=='T'){scanf("%d",&k);root[1&i]=merge(root[1&i],f[k]);f[k]=0;sum[(1&i)+105]+=sum[k];}else if(op[0]=='C'){if(nd[root[0]].v>nd[root[1]].v){root[0]=merge(root[0],root[1]);sum[105]+=sum[106];root[1]=0;sum[106]=0;}else if(nd[root[0]].v<nd[root[1]].v){root[1]=merge(root[0],root[1]);sum[106]+=sum[105];root[0]=0;sum[105]=0;}}else if(op[0]=='L'){root[1&i]=pop(root[1&i]);sum[(1&i)+105]--;}else if(op[0]=='A'){scanf("%d",&k);nd[root[1&i]].v+=k;}else if(op[0]=='E'){scanf("%d",&k);root[1&i]=pop(root[1&i]);root[1&i]=merge(root[1&i],newnode(k));}}if(sum[105]>sum[106]) happy++;else wolf++;printf("%d:%d\n",sum[106],sum[105]);}if(happy>wolf) puts("I will be back!!");else puts("Hahaha...I win!!");}return 0;
}
这篇关于HDU 3031 To Be Or Not To Be的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!