zoukankan      html  css  js  c++  java
  • 题解 [SDOI2010]猪国杀

    代码成功卡到(600)行以内

    曾经发誓一天切掉的我打了两周。。。

    先看题

    要点还是挺多的,即使是像我这样熟悉三国杀的同(wán)学(jiā),也要认真看。


    首先是基本牌的部分。

    杀:在自己的回合内,对攻击范围内除自己以外的一名角色使用。如果没有被『闪』抵消,则造成1点伤害。无论有无武器,杀的攻击范围都是1;

    直接看看自己的下家跳没跳,跳了的话就看看是不是一伙然后一刀砍下去,没跳直接(return)

    注意,用了杀之后自己的身份就完全暴露了。


    闪:当你受到杀的攻击时,可以弃置一张闪来抵消杀的效果;

    这个没什么需要解释的吧,直接暴力看看有没有闪就行了。


    桃:在自己的回合内,如果自己的体力值不等于体力上限,那么使用一个桃可以为自己补充一点体力,否则不能使用桃;桃只能对自己使用;在自己的回合外,如果自己的血变为0或者更低,那么也可以使用;

    注意:不能对别人使用!!!


    猪哥连弩:武器,攻击范围1,出牌阶段你可以使用任意张杀;

    注意:即使之前有了也要再装一遍,把之前的顶掉(不愧是猪)。


    看上去很简单,但是细节很多。

    首先就是装上猪哥连弩之后前面的杀也是可以用的,需要(i=0)重新扫一遍。

    还有题目描述中说保证牌数够用,不要相信它,牌堆没了就一直摸最后一张牌。

    一个回合只能用一次杀(除非装了猪哥连弩)。


    好了现在(10)分到手了。

    接下来我们看锦囊牌。

    决斗:出牌阶段,对除自己以外任意一名角色使用,由目标角色先开始,自己和目标角色轮流弃置一张杀,首先没有杀可弃的一方受到1点伤害,另一方视为此伤害的来源;

    这个就一个(while)就暴力判断一下有没有杀就完事了,需要注意的是忠臣接收到主公的杀要直接掉血。

    还有伤害来源不是用牌者而是对方。

    要判断是跳反还是跳忠。


    南猪入侵:出牌阶段,对除你以外所有角色使用,按逆时针顺序从使用者下家开始依次结算,除非弃置一张杀,否则受到1点伤害;

    这里判断一下死了就直接跳过,蒟蒻因为这个调了好几天。。。

    每个人都要判断。


    万箭齐发:和南猪入侵类似,不过要弃置的不是杀而是闪;

    做法和题上说的也一样,把杀换成闪就完事了。


    还是很麻烦的,最后提醒一下按理来说除了桃使用任意一张手牌后都要重新扫一遍,比如说万箭齐发杀死了你的下家,然后前面的杀有可能就有了目标。

    好的现在我们拿到(30)分了。


    最后一个最恶心的部分——无懈可击。

    orz一下各路用奇偶性来判断的神仙。

    蒟蒻只会递归。。。

    那么明确一下,无懈可击后,自己和对方的身份都已经暴露了。

    判断一下受攻击的人跳没跳身份,如果没跳就直接(return)

    记录一个(flag)判断是在献殷勤还是表敌意。

    然后暴力枚举判断就行了,找到之后下一层递归要(flag)^=(1)

    至此,猪国杀成功(AC)


    上代码

    #define N 2001001
    #define MAX 2001
    #define re register
    #define inf 1e18
    #define eps 1e-10
    using namespace std;
    typedef long long ll;
    typedef double db;
    inline void read(re ll &ret)
    {
    	ret=0;re char c=getchar();re bool pd=false;
    	while(!isdigit(c)){pd|=c=='-';c=getchar();}
    	while(isdigit(c)){ret=(ret<<1)+(ret<<3)+(c&15);c=getchar();}
    	ret=pd?-ret:ret;
    	return;
    }
    ll n,m;
    struct zhu
    {
    	ll paishu,leixing,xueliang;//leixing=1为主猪,2为忠猪,3为反猪 
    	char pai[1000001];
    	bool zhuge,si,tiaozhong,tiaofan,leifan;
    }a[11];
    char s[N];
    char paidui[2001];
    ll head;
    inline void print()
    {
    	for(re int i=1;i<=n;i++)
    	{
    		if(a[i].si)
    			printf("DEAD
    ");
    		else
    		{
    //			cout<<i<<" "<<a[i].xueliang<<endl;
    			for(re int j=1;j<=a[i].paishu;j++)
    			{
    				if(j>1)
    					putchar(' ');
    				putchar(a[i].pai[j]);
    			}
    			putchar('
    ');
    		}
    	}
    	return;
    }
    inline void init()
    {
    	read(n);
    	read(m);
    	for(re int i=1;i<=n;i++)
    	{
    		a[i].si=false;
    		a[i].xueliang=4;
    		a[i].zhuge=false;
    		scanf("%s",s+1);
    		if(s[1]=='M')
    			a[i].leixing=1;
    		else if(s[1]=='Z')
    			a[i].leixing=2;
    		else
    			a[i].leixing=3;
    		for(re int j=1;j<=4;j++)
    		{
    			scanf("%s",s+1);
    			a[i].pai[++a[i].paishu]=s[1];
    		}
    	}
    	for(re int i=1;i<=m;i++)
    	{
    		scanf("%s",s+1);
    		paidui[i]=s[1];
    	}
    }
    inline void yongpai(re ll num,re ll pos)
    {
    	for(re int i=pos+1;i<=a[num].paishu;i++)
    		a[num].pai[i-1]=a[num].pai[i];
    	a[num].paishu--;
    	return;
    }
    
    inline void jieshu()
    {
    	re bool mp=true,fp=true;
    	for(re int i=1;i<=n;i++)
    	{
    		if(a[i].xueliang!=0&&a[i].leixing==3)
    			mp=false;
    		if(a[i].xueliang!=0&&a[i].leixing==1)
    			fp=false;
    	}
    	if(mp)
    	{
    		printf("MP
    ");
    		print();
    		exit(0);
    	}
    	if(fp)
    	{
    		printf("FP
    ");
    		print();
    		exit(0);
    	}
    	return;
    }
    inline void mopai(re ll pos,re ll num)
    {
    	for(re int i=1;i<=num;i++)
    	{
    		if(++head>m)
    			head=m;
    		a[pos].pai[++a[pos].paishu]=paidui[head];
    	}
    		
    	return;
    }
    inline void si(re ll num,re ll laiyuan)
    {
    //	cout<<num<<" "<<laiyuan<<endl;
    	if(a[num].xueliang>=1)
    		return;
    	for(re int i=1;i<=a[num].paishu;i++)
    	{
    		if(a[num].pai[i]=='P')
    		{
    			yongpai(num,i);
    			a[num].xueliang++;
    			break;
    		}
    	}
    	if(a[num].xueliang<1)
    	{
    		a[num].si=true;
    		jieshu();
    		if(a[num].leixing==3)
    			mopai(laiyuan,3);
    		else if(a[num].leixing==2&&a[laiyuan].leixing==1)
    		{
    			a[laiyuan].paishu=0;
    			a[laiyuan].zhuge=false;
    		}
    	}
    	return;
    }
    inline bool shan(re ll pos)
    {
    	for(re int i=1;i<=a[pos].paishu;i++)
    	{
    		if(a[pos].pai[i]=='D')
    		{
    			yongpai(pos,i);
    			return true;
    		}
    	}
    	return false;
    }
    inline bool sha(re ll pos,re ll num)
    {
    	for(re int i=pos+1;i<=n;i++)
    	{
    		if(a[i].si)continue;
    		if((a[pos].leixing==1&&(a[i].tiaofan||a[i].leifan))||(a[pos].leixing==2&&a[i].tiaofan)||(a[pos].leixing==3&&(a[i].leixing==1||a[i].tiaozhong)))
    		{
    			yongpai(pos,num);
    			if(a[i].tiaofan)
    			{
    				a[pos].tiaozhong=true;
    				a[pos].leifan=false;
    			}
    			else if(a[i].tiaozhong||a[i].leixing==1)
    				a[pos].tiaofan=true;
    			if(!shan(i))
    			{
    				a[i].xueliang--;
    				si(i,pos);
    			}
    			return true;
    		}
    		return false;	
    	}
    	for(re int i=1;i<pos;i++)
    	{
    		if(a[i].si)continue;
    		if((a[pos].leixing==1&&(a[i].tiaofan||a[i].leifan))||(a[pos].leixing==2&&a[i].tiaofan)||(a[pos].leixing==3&&(a[i].leixing==1||a[i].tiaozhong)))
    		{
    			yongpai(pos,num);
    			if(a[i].tiaofan)
    			{
    				a[pos].tiaozhong=true;
    				a[pos].leifan=false;
    			}
    			else if(a[i].tiaozhong||a[i].leixing==1)
    				a[pos].tiaofan=true;
    			if(!shan(i))
    			{
    				a[i].xueliang--;
    				si(i,pos);
    			}
    			return true;
    		}
    		return false;	
    	}
    }
    inline bool wuxie(re ll pos,re ll to,re bool pd)
    {
    	if(!a[to].tiaofan&&!a[to].tiaozhong&&a[to].leixing!=1)return false;
    	if(pd)
    	{
    		re bool flag=false;
    		for(re int i=pos;i<=n;i++)
    		{
    			if(a[i].si)continue;
    			if((a[to].leixing==1&&(a[i].leixing==3))||(a[to].tiaozhong&&(a[i].leixing==3))||(a[to].tiaofan&&(a[i].leixing==1||a[i].leixing==2)))
    				continue;
    			for(re int j=1;j<=a[i].paishu;j++)
    			{
    				if(a[i].pai[j]=='J')
    				{
    					yongpai(i,j);
    					if(a[to].leixing==1)
    					{
    						a[i].tiaozhong=true;
    						a[i].leifan=false;
    					}
    					else if(a[to].leixing==2)
    					{
    						a[i].tiaozhong=true;
    						a[i].leifan=false;
    					}
    					else
    					{
    						a[i].tiaofan=true;
    						a[i].leifan=false;
    					}
    				//	if((a[i].leixing==1&&a[pos].leixing==2)||(a[i].leixing==2&&(a[pos].leixing==1||a[pos].leixing==2))||(a[i].leixing==3&&a[pos].leixing==3))
    					return !wuxie(i,to,false);
    				//	else
    				//		return !wuxie(i,to,true);
    				}
    			}
    		}
    		for(re int i=1;i<pos;i++)
    		{
    			if(a[i].si)continue;
    			if((a[to].leixing==1&&(a[i].leixing==3))||(a[to].tiaozhong&&(a[i].leixing==3))||(a[to].tiaofan&&(a[i].leixing==1||a[i].leixing==2)))
    				continue;
    			for(re int j=1;j<=a[i].paishu;j++)
    			{
    				if(a[i].pai[j]=='J')
    				{
    					yongpai(i,j);
    					if(a[to].leixing==1)
    					{
    						a[i].tiaozhong=true;
    						a[i].leifan=false;
    					}
    					else if(a[to].leixing==2)
    					{
    						a[i].tiaozhong=true;
    						a[i].leifan=false;
    					}
    					else
    					{
    						a[i].tiaofan=true;
    						a[i].leifan=false;
    					}
    			//		if((a[i].leixing==1&&a[pos].leixing==2)||(a[i].leixing==2&&(a[pos].leixing==1||a[pos].leixing==2))||(a[i].leixing==3&&a[pos].leixing==3))
    						return !wuxie(i,to,false);
    			//		else
    			//			return !wuxie(i,to,true);
    				}
    			}
    			
    		}
    		return false;
    	}
    	else
    	{
    		re bool flag=false;
    		for(re int i=pos;i<=n;i++)
    		{
    			if(a[i].si)continue;
    			if(!((a[to].leixing==1&&(a[i].leixing==3))||(a[to].tiaozhong&&(a[i].leixing==3))||(a[to].tiaofan&&(a[i].leixing==1||a[i].leixing==2))))
    				continue;
    			for(re int j=1;j<=a[i].paishu;j++)
    			{
    				if(a[i].pai[j]=='J')
    				{
    					yongpai(i,j);
    					if(a[to].leixing==1)
    					{
    						a[i].tiaofan=true;
    						a[i].leifan=false;
    					}
    					else if(a[to].leixing==2)
    					{
    						a[i].tiaofan=true;
    						a[i].leifan=false;
    					}
    					else
    					{
    						a[i].tiaozhong=true;
    						a[i].leifan=false;
    					}
    					return !wuxie(i,to,true);
    				}
    			}
    		}
    		for(re int i=1;i<pos;i++)
    		{
    			if(a[i].si)continue;
    			if(!((a[to].leixing==1&&(a[i].leixing==3))||(a[to].tiaozhong&&(a[i].leixing==3))||(a[to].tiaofan&&(a[i].leixing==1||a[i].leixing==2))))
    				continue;
    			for(re int j=1;j<=a[i].paishu;j++)
    			{
    				if(a[i].pai[j]=='J')
    				{
    					yongpai(i,j);
    					if(a[to].leixing==1)
    					{
    						a[i].tiaofan=true;
    						a[i].leifan=false;
    					}
    					else if(a[to].leixing==2)
    					{
    						a[i].tiaofan=true;
    						a[i].leifan=false;
    					}
    					else
    					{
    						a[i].tiaozhong=true;
    						a[i].leifan=false;
    					}
    					return !wuxie(i,to,true);
    				}
    			}
    			
    		}
    		return false;
    	}
    }
    inline bool juedou(re ll pos,re ll num)
    {
    	for(re int i=pos+1;i<=n;i++)
    	{
    		if(a[i].si)continue;
    		if((a[pos].leixing==1&&(a[i].tiaofan||a[i].leifan))||(a[pos].leixing==2&&a[i].tiaofan)||(a[pos].leixing==3&&a[i].leixing==1))
    		{
    			yongpai(pos,num);
    			if(a[i].leixing==3)
    			{
    				a[pos].tiaozhong=true;
    				a[pos].leifan=false;
    			}
    			else if(a[i].tiaozhong||a[i].leixing==1)
    				a[pos].tiaofan=true;
    			if(wuxie(pos,i,true))
    				return true;
    			if(a[pos].leixing==1&&a[i].leixing==2)
    			{
    				a[i].xueliang--;
    				si(i,pos);
    				return true;
    			}
    			re ll turn=i;
    			while(true)
    			{
    				re bool flag=false;
    				for(re int j=1;j<=a[turn].paishu;j++)
    				{
    					if(a[turn].pai[j]=='K')
    					{
    						yongpai(turn,j);
    						flag=true;
    						break;
    					}
    				}
    				if(!flag)
    				{
    					a[turn].xueliang--;
    					si(turn,turn==pos?i:pos);
    					return true;
    				}
    				if(turn==i)
    					turn=pos;
    				else
    					turn=i;
    			}
    		}
    	}
    	for(re int i=1;i<pos;i++)
    	{
    		if(a[i].si)continue;
    		if((a[pos].leixing==1&&(a[i].tiaofan||a[i].leifan))||(a[pos].leixing==2&&a[i].tiaofan)||(a[pos].leixing==3&&a[i].leixing==1))
    		{
    			yongpai(pos,num);
    			if(a[i].leixing==3)
    			{
    				a[pos].tiaozhong=true;
    				a[pos].leifan=false;
    			}
    			else if(a[i].tiaozhong||a[i].leixing==1)
    				a[pos].tiaofan=true;
    			if(wuxie(pos,i,true))
    				return true;
    			if(a[pos].leixing==1&&a[i].leixing==2)
    			{
    				a[i].xueliang--;
    				si(i,pos);
    				return true;
    			}
    			re ll turn=i;
    			while(true)
    			{
    				re bool flag=false;
    				for(re int j=1;j<=a[turn].paishu;j++)
    				{
    					if(a[turn].pai[j]=='K')
    					{
    						yongpai(turn,j);
    						flag=true;
    						break;
    					}
    				}
    				if(!flag)
    				{
    					a[turn].xueliang--;
    					si(turn,turn==pos?i:pos);
    					return true;
    				}
    				if(turn==i)
    					turn=pos;
    				else
    					turn=i;
    			}
    		}
    	}
    	return false;
    }
    inline void nanman(re ll pos,re ll num)
    {
    //	cout<<pos<<" "<<num<<endl;
    	yongpai(pos,num);
    	for(re int i=pos+1;i<=n;i++)
    	{
    		if(a[i].si)continue;
    		if(wuxie(pos,i,true))continue;
    		re bool flag=false;
    		for(re int j=1;j<=a[i].paishu;j++)
    		{
    			if(a[i].pai[j]=='K')
    			{
    				yongpai(i,j);
    				flag=true;
    				break;
    			}
    		}
    		if(!flag)
    		{
    			a[i].xueliang--;
    			if(a[i].leixing==1&&!a[pos].tiaozhong&&!a[pos].tiaofan)
    				a[pos].leifan=true;
    			si(i,pos);
    		}
    	}
    	for(re int i=1;i<pos;i++)
    	{
    		if(a[i].si)continue;
    		if(wuxie(pos,i,true))continue;
    		re bool flag=false;
    		for(re int j=1;j<=a[i].paishu;j++)
    		{
    			if(a[i].pai[j]=='K')
    			{
    				yongpai(i,j);
    				flag=true;
    				break;
    			}
    		}
    		if(!flag)
    		{
    			a[i].xueliang--;
    			if(a[i].leixing==1&&!a[pos].tiaozhong&&!a[pos].tiaofan)
    				a[pos].leifan=true;
    			si(i,pos);
    		}
    	}
    	return;
    }
    inline void wanjian(re ll pos,re ll num)
    {
    //	cout<<pos<<" "<<num<<endl;
    	yongpai(pos,num);
    	for(re int i=pos+1;i<=n;i++)
    	{
    		if(a[i].si)continue;
    		if(wuxie(pos,i,true))continue;
    		if(!shan(i))
    		{
    			a[i].xueliang--;
    			if(a[i].leixing==1&&!a[pos].tiaozhong&&!a[pos].tiaofan)
    				a[pos].leifan=true;
    			si(i,pos);
    		}
    	}
    	for(re int i=1;i<pos;i++)
    	{
    		if(a[i].si)continue;
    		if(wuxie(pos,i,true))continue;
    		if(!shan(i))
    		{
    			a[i].xueliang--;
    			if(a[i].leixing==1&&!a[pos].tiaozhong&&!a[pos].tiaofan)
    				a[pos].leifan=true;
    			si(i,pos);
    		}
    	}
    	return;
    }
    inline void chupai(re ll pos)
    {
    	re bool chuguosha=false;
    	for(re int i=1;i<=a[pos].paishu;i++)
    	{
    		if(a[pos].si)
    			return;
    		if(a[pos].pai[i]=='P')
    		{
    			if(a[pos].xueliang<4)
    			{
    				yongpai(pos,i);
    				i=0;
    				a[pos].xueliang++;
    			}
    		}
    		else if(a[pos].pai[i]=='K'&&(!chuguosha||a[pos].zhuge))
    		{
    			if(sha(pos,i))
    			{
    				i=0;
    				chuguosha=true;
    			}
    		}
    		else if(a[pos].pai[i]=='F')
    		{
    			if(juedou(pos,i))
    				i=0;
    		}
    		else if(a[pos].pai[i]=='N')
    		{
    			nanman(pos,i);
    			i=0;
    		}
    		else if(a[pos].pai[i]=='W')
    		{
    			wanjian(pos,i);
    			i=0;
    		}
    		else if(a[pos].pai[i]=='Z')
    		{
    			a[pos].zhuge=true;
    			yongpai(pos,i);
    			i=0;
    		}
    	//	cout<<i<<endl;
    	}
    	return;
    }
    /*
    『桃(P)』
    『杀(K)』
    『闪(D)』
    『决斗(F)』
    『南猪入侵(N)』
    『万箭齐发(W)』
    『无懈可击(J)』
    『猪哥连弩(Z)』
    */
    inline void work()
    {
    	re ll num=0;
    	while(true)
    	{
    		num%=n;
    		num++;
    		if(a[num].si)
    			continue;
    		mopai(num,2);
    		chupai(num);
    	}
    }
    signed main()
    {
    	init();
    	work();
    	exit(0);
    }
    //[SDOI2010]猪国杀
    
  • 相关阅读:
    HYSBZ 3813 奇数国
    HYSBZ 4419 发微博
    HYSBZ 1079 着色方案
    HYSBZ 3506 排序机械臂
    HYSBZ 3224 Tyvj 1728 普通平衡树
    Unity 3D,地形属性
    nginx 的naginx 种包含include关键字
    Redis 出现NOAUTH Authentication required解决方案
    mysql 8.0出现 Public Key Retrieval is not allowed
    修改jar包里的源码时候需要注意的问题
  • 原文地址:https://www.cnblogs.com/CelticBlog/p/13531627.html
Copyright © 2011-2022 走看看