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]猪国杀
    
  • 相关阅读:
    集中式(SVN)和分布式(Git)版本控制系统的简单比较
    Mac 提示安装包已损坏
    React 获取 url 参数 —— this.props.match
    编写一个 Chrome 浏览器扩展程序
    webpack 配置学习笔记
    Python 进阶学习笔记
    Python 入门学习笔记
    (转)Unity3d各种坑
    unity3d 网页游戏客户端工程构建方案
    (转)在Unity3D的网络游戏中实现资源动态加载
  • 原文地址:https://www.cnblogs.com/CelticBlog/p/13531627.html
Copyright © 2011-2022 走看看