Solution -「SDOI 2010」猪国杀

cirnovsky /

§ 一个正常人是不会做这种题的...

某年某月某天,我校机房有个可怜人被人强行立了个flag:9月月底做不出来luoguP2482就女装!于是他拼命的调代码。5分,10分,25分......95分。最后实在不行了求救了机房大佬WY才AC。

这位同志的精神感动了机房,于是全机房都开始疯狂的调这道题。我也不幸幸运的成为了其中的一员。

其实这道题就是模拟,大概是因为我平时闲的没事喜欢做游戏,所以感觉挺简单的。

把各种行为封装成自由函数,当然如果你想建class也没有问题。

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

/*
¡¾ÌÒ¡¿ P
¡¾É±¡¿ K
¡¾ÉÁ¡¿ D
¡¾¾ö¶·¡¿ F
¡¾ÄÏÂùÈëÇÖ¡¿ N
¡¾Íò¼ýÆë·¢¡¿ W
¡¾ÎÞи¿É»÷¡¿ J
¡¾Öî¸ðÁ¬åó¡¿ Z
*/

const int MAX_PLAYER_NUM = 100 + 5;
const int MAX_CARD_NUM = 2000 + 5;
class PIG
{
public:
	int		card_num;
	int		life_num;
	int		_next;
	int		_last;
	char	identity;
	char	card[MAX_CARD_NUM];
	bool	isGetedZgln;
} A[MAX_PLAYER_NUM];
char	id_in_king[MAX_PLAYER_NUM]; 	//在主公眼里诸猪的身份
char	card_set[MAX_CARD_NUM];
char	scanner[MAX_PLAYER_NUM];
int		n, m, bad_man_num;
bool	GG;  //主公是否GG

inline	 void		initt(	 	 		   	    );
inline	 void		start(		  	 	 	    );
inline	 void		mopai(       int fuck       );  //不知道怎么命名了...
inline	 void		nmrqq(		 int fuck       );
inline	 void		wjqff(		 int fuck       );
inline	 void		jisha( int Killer, int GGer );
inline	 void		killl( int Killer, int GGer );
inline	 void		jdddd( int Killer, int GGer );
inline	 bool		wxkjj(int x1, int x2, int x3);   //为了对齐

signed main()
{
	initt();
	start();
	if (A[1].life_num <= 0)	puts("FP");
	else puts("MP");
	for (int i = 1; i <= n; ++i)
	{
		if (A[i].life_num <= 0)	puts("DEAD");
		else
		{
			for (int j = 1; j <= A[i].card_num; ++j)
				if (A[i].card[j] != 'U')	printf("%c ", A[i].card[j]);
			puts("");
		}
	}
	return 0;
}

inline void	initt()
{
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i)	A[i]._next = i + 1, A[i]._last = i - 1;
	A[n]._next = 1, A[1]._last = n;
	for (int i = 1; i <= n; ++i)
	{
		for (int j = 1; j < MAX_CARD_NUM; ++j)	A[i].card[j] = 'U';
		scanf("%s", scanner);
		A[i].identity = scanner[0];
		for (int j = 1; j < 5; ++j)	scanf("%s", scanner), A[i].card[j] = scanner[0];
		A[i].life_num = A[i].card_num = 4;
		if (A[i].identity == 'F')	bad_man_num++;
		A[i].isGetedZgln = false;
	}
	id_in_king[1] = 'M';
	for (int i = 2; i <= n; ++i)	id_in_king[i] = 'U';
	for (int i = 1; i <= m; ++i)	scanf("%s", scanner), card_set[m - i + 1] = scanner[0];
}

inline void start()
{
	char now_card;
	GG = true;
	if (bad_man_num) GG = false;
	if (GG)		return;
	for (int i = 1; i; i = A[i]._next)
	{
		mopai(i), mopai(i);
		bool isKilled = true;
		for (int j = 1; j <= A[i].card_num; ++j)
		{
			if (A[i].card[j] != 'U')
			{
				if (!A[i].life_num)	break;
				now_card = A[i].card[j];

				if (now_card == 'P')
				{
					if (A[i].life_num != 4)	A[i].life_num++, A[i].card[j] = 'U';
					continue;
				}

				if (now_card == 'K')
				{
					if (!isKilled && !A[i].isGetedZgln)	continue;
					if ((A[i].identity == 'M') && (id_in_king[A[i]._next] != 'L') && (id_in_king[A[i]._next] != 'F'))
						continue;
					if ((A[i].identity == 'Z') && (id_in_king[A[i]._next] != 'F'))
						continue;
					if ((A[i].identity == 'F') && (id_in_king[A[i]._next] != 'Z') && (id_in_king[A[i]._next] != 'M'))
						continue;
					A[i].card[j] = 'U';
					killl(i, A[i]._next);
					id_in_king[i] = A[i].identity;
					isKilled = false;
					if (GG)	return;
					continue;
				}

				if (now_card == 'F')
				{
					if (A[i].identity == 'F')
					{
						A[i].card[j] = 'U';
						jdddd(i, 1);
						id_in_king[i] = A[i].identity;
						if (GG)	return;
						j = 0;
						continue;
					}
					for (int k = A[i]._next; k != i; k = A[k]._next)
					{
						if ((A[i].identity == 'M' && (id_in_king[k] == 'L' || id_in_king[k] == 'F')) || (A[i].identity == 'Z' && id_in_king[k] == 'F'))
						{
							A[i].card[j] = 'U';
							jdddd(i, k);
							id_in_king[i] = A[i].identity;
							if (GG)	return;
							j = 0;
							break;
						}
					}
					continue;
				}
					

				if (now_card == 'N')
				{
					A[i].card[j] = 'U';
					nmrqq(i);
					if (GG)	return;
					j = 0;
					continue;
				}

				if (now_card == 'W')
				{
					A[i].card[j] = 'U';
					wjqff(i);
					if (GG)	return;
					j = 0;
					continue;
				}

				if (now_card == 'Z')
				{
					A[i].isGetedZgln = true;
					A[i].card[j] = 'U';
					j = 0;
					continue;
				}
			}
		}
	}
}

inline void mopai(int fuck)
{
	if (!m)	m++;
	A[fuck].card[++A[fuck].card_num] = card_set[m];
	m--;
}

inline void nmrqq(int fuck)
{
	for (int shit = A[fuck]._next; shit != fuck; shit = A[shit]._next)
	{
		if (!wxkjj(fuck, shit, 1))
		{
			int i;
			for (i = 1; i <= A[shit].card_num; ++i)
			{
				if (A[shit].card[i] == 'K')
				{
					A[shit].card[i] = 'U';
					break;
				}
			}
			if (i > A[shit].card_num)
			{
				A[shit].life_num--;
				if (shit == 1 && id_in_king[fuck] == 'U')	id_in_king[fuck] = 'L';
				if (!A[shit].life_num) jisha(fuck, shit);
				if (GG)	return;
			}
		}
	}
}

inline void wjqff(int fuck)
{
	for (int shit = A[fuck]._next; shit != fuck; shit = A[shit]._next)
	{
		if (!wxkjj(fuck, shit, 1))
		{
			int i;
			for (i = 1; i <= A[shit].card_num; ++i)
			{
				if (A[shit].card[i] == 'D')
				{
					A[shit].card[i] = 'U';
					break;
				}
			}
			if (i > A[shit].card_num)
			{
				A[shit].life_num--;
				if (shit == 1 && id_in_king[fuck] == 'U')	id_in_king[fuck] = 'L';
				if (!A[shit].life_num)	jisha(fuck, shit);
				if (GG)	return;
			}
		}
	}
}

inline void jisha(int Killer, int GGer)
{
	for (int i = 1; i <= A[GGer].card_num; ++i)
	{
		if (A[GGer].card[i] == 'P')
		{
			A[GGer].card[i] = 'U';
			A[GGer].life_num++;
			return ;
		}
	}
	
	A[A[GGer]._next]._last = A[GGer]._last;
	A[A[GGer]._last]._next = A[GGer]._next;
	
	if (GGer == 1)
	{
		GG = true;
		return ;
	}
	
	if (A[GGer].identity == 'F')	bad_man_num--;
	
	if (!bad_man_num)
	{
		GG = true;
		return ;
	}
	
	if (A[GGer].identity == 'F')	mopai(Killer), mopai(Killer), mopai(Killer);
	
	if (A[GGer].identity == 'Z' && A[Killer].identity == 'M')	A[Killer].card_num = 0, A[Killer].isGetedZgln = false;
}

inline void killl(int Killer, int GGer)
{
	for (int i = 1; i <= A[GGer].card_num; ++i)
	{
		if (A[GGer].card[i] == 'D')
		{
			A[GGer].card[i] = 'U';
			return ;
		}
	}
	A[GGer].life_num--;
	if (!A[GGer].life_num)	jisha(Killer, GGer);
}

inline void jdddd(int Killer, int GGer)
{
	int fuck, shit;
	if (wxkjj(Killer, GGer, 1))	return ;
	
	if (Killer == 1 && A[GGer].identity == 'Z')
	{
		A[GGer].life_num--;
		if (!A[GGer].life_num)	jisha(Killer, GGer);
		return ;
	}
	
	fuck = shit = 1;
	
	while (233)
	{
		while (A[GGer].card[fuck] != 'K' && fuck <= A[GGer].card_num)	++fuck;
		if (fuck > A[GGer].card_num)
		{
			A[GGer].life_num--;
			if (!A[GGer].life_num)	jisha(Killer, GGer);
			return ;
		}
		else A[GGer].card[fuck] = 'U';
		
		while (A[Killer].card[shit] != 'K' && shit <= A[Killer].card_num)	++shit;
		if (shit > A[Killer].card_num)
		{
			A[Killer].life_num--;
			if (!A[Killer].life_num)	jisha(GGer, Killer);
			return ;
		}
		else A[Killer].card[shit] = 'U';
	}
}

inline bool wxkjj(int x1, int x2, int x3)
{
	int i = x1;
	while (233)
	{
		if (x3 == 1)
		{
			if (id_in_king[x2] == A[i].identity || (id_in_king[x2] == 'M' && A[i].identity == 'Z') || (id_in_king[x2] == 'Z' && A[i].identity == 'M'))
			{
				for (int j = 1; j <= A[i].card_num; ++j)
				{
					if (A[i].card[j] == 'J')
					{
						A[i].card[j] = 'U';
						id_in_king[i] = A[i].identity;
						return !wxkjj(i, x1, 0);
					}
				}
			}
		}
		
		else
		{
			if (((A[i].identity == 'M' || A[i].identity == 'Z') && id_in_king[x1] == 'F') || (A[i].identity == 'F' && (id_in_king[x1] == 'M' || id_in_king[x1] == 'Z')))
			{
				for (int j = 1; j <= A[i].card_num; ++j)
				{
					if (A[i].card[j] == 'J')
					{
						A[i].card[j] = 'U';
						id_in_king[i] = A[i].identity;
						return !wxkjj(i, x1, 0);
					}
				}
			}
		}
		i = A[i]._next;
		if (i == x1)	break;
	}
	return false;
}