社区讨论

猪国杀40分求条

灌水区参与者 6已保存回复 6

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
6 条
当前快照
1 份
快照标识符
@lzv12xl6
此快照首次捕获于
2024/08/15 16:38
2 年前
此快照最后确认于
2024/08/15 18:44
2 年前
查看原帖
我们机构老师带我,看了一遍他的标程,琢磨嘞二十分钟,加上笔记本上记的
又写了两天,重构了两次,终于。。。。。。
40分了
CPP
/*
Date: 2024-08-15 11:45:14
made by LeoLiu
Problem: 
P2482 [SDOI2010] 猪国杀
Ideas: 
由于忠猪和反猪在亮明身份之前大家都不会知道他们的身份
所以对于每个猪都建立一个数组存储对每一个猪的印象

存储猪:
结构体
包含
血量
身份
桶数组 存储 手牌 & 武器
桶数组 存储 印象(初始化自己和主猪)

用牌规则
桃 体力不满时一定使用桃,回合外如果濒死一定用桃
杀 对自己的左右两边的角色使用 
忠猪 优先杀反猪,没有亮身份的时候不杀
反猪 优先杀主猪,或者逆时针方向第一只忠猪,没有则不杀
主猪 优先杀反猪,或者逆时针方向第一只反猪,没有则不杀
闪 被杀时一定出闪

表敌意和献殷勤
忠猪 有无懈可击的时候一定挡下自己的或者主猪的



样例:
3 0
MP K J J J
ZP P J J J
FP K K K K
O(?)
*/
#include <bits/stdc++.h>
#define For(i , a , b) for(int i = (a) ; i <= (b) ; i ++)
#define FFor(i , a , b) for(int i = (a) ; i >= (b) ; i --)
#define ll long long
#define endl '\n'
using namespace std;
const int dx[] = {0 , 1 , 0 , -1};
const int dy[] = {1 , 0 , -1 , 0};
const int N = 10 + 7;
const int M = 2e3 + 7;
const int Mod = 998244353;
struct player{
	int ID , HP , tot_cards , pre ,  nxt , pigid;
	char cards[M];
	bool special , weapon;
}pigs[N];
int n , m , top , FPcnt;
char cards[M];
bool gameover;

void read(int &__num) {
	int x = 0 , f = 1;
	char ch = getchar();
	while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0' && ch<='9'){x*=10,x+=ch-'0';ch=getchar();}
	__num = x*f;
}
void write (int x , char end_ch = endl) {
	int st[105] , top = 0;
	do st[++ top] = x % 10 , x /= 10; while (x);
	while (top)	putchar(st[top --] + '0');
	putchar (end_ch);
}

void printcard(int);			//输出打印手牌
void getcard(int);				//摸牌
int findcard(int , char);		//寻找要出的牌
void getfriend(int , int);		//寻找目前同一阵营的猪(对于某个角色而言)
void getenemy(int , int);		//寻找目前的敌人
void dechp(int , int);			//死亡
bool enemy(int , int);			//表敌意
bool friendly(int , int);		//献殷勤
bool usecard_j(int , int , int);//用无懈可击
void usecard_k(int , int);		//用杀
void usecard_f(int , int);		//用决斗
void usecard_n(int , int);		//用南蛮入侵
void usecard_w(int , int);		//用万箭齐发
void rungame();					//游戏过程

int main(){
	read(n) , read (m);
	For (i , 1 , N - 1){
		For (j , 1 , M - 1){
			pigs[i] . cards[j] = 'X';
		}
		pigs[i] . HP = 4;
	}
	For (i , 1 , n){
		string ShenFen , s;
		cin >> ShenFen;
		For (j , 1 , 4){
			cin >> s;
			pigs[i] . cards[j] = s[0];
		}
		pigs[i] . tot_cards = 4;
		if (ShenFen[0] == 'M') pigs[i] . ID = 1 , pigs[i] . pigid = 1;
		else if (ShenFen[0] == 'Z') pigs[i] . ID = 2;
		else pigs[i] . ID = 3 , FPcnt ++;
		pigs[i] . nxt = i + 1;
		pigs[i] . pre = i - 1;
	}
	pigs[n] . nxt = 1;
	pigs[1] . pre = n;
	For (i , 1 , m){
		string s;
		cin >> s;
		cards[i] = s[0];
	}
	top = 1;
	rungame();
	if (pigs[1] . HP <= 0) printf("FP\n");
	else printf("MP\n");
	For (i , 1  ,n){
		if (pigs[i] . HP <= 0) printf("DEAD\n");
		else					printcard(i);
	}
	return 0;
}

void usecard_f(int from , int to){
	if (pigs[from] . ID == 1 && pigs[to] . ID == 2){
		dechp(from , to);
		return;
	}
	while (true){
		bool flag1 = findcard(to , 'K');
		if (!flag1){
			dechp(from , to);
			return;
		}
		bool flag2 = findcard(from , 'K');
		if (!flag2){
			dechp(to , from);
			return;
		}
	}
}
void usecard_n(int from , int to){
	while (true){
		if (gameover) return;
		if (!usecard_j(from , to , 0)){
			bool flag = findcard(to , 'K');
			if (!flag){
				if (pigs[to] . ID == 1 && pigs[from] . pigid == 0){
					pigs[from] . special = true;
				}
				dechp(from , to);
			}
		}
		to = pigs[to] . nxt;	
		if (to == from) return;
	}
}
void usecard_w(int from , int to){
	while (true){
		if (gameover) return;
		if (!usecard_j(from , to , 0)){
			bool flag = findcard(to , 'D');
			if (!flag){
				if (pigs[to] . ID == 1 && pigs[from] . pigid == 0){
					pigs[from] . special = true;
				}
				dechp(from , to);
			}
		}
		to = pigs[to] . nxt;	
		if (to == from) return;
	}
}
void rungame(){
	while (true){	
		For (i , 1 , n){
			if (gameover) return;
			if (pigs[i] . HP <= 0) continue;
			getcard(i); getcard(i);
			bool use_k = true;
			for (int j = 1 ; j <= pigs[i] . tot_cards ; j ++){
				if (pigs[i] . cards[j] == 'X') continue;
				if (gameover) return;
				switch (pigs[i] . cards[j]){
					case 'P':{
						if (pigs[i] . HP < 4){
							pigs[i] . cards[j] = 'X';
							pigs[i] . HP ++;
						}
						break;
					}
					case 'K':{
						if (use_k && enemy(i , pigs[i] . nxt)){
							pigs[i].cards[j] = 'X';
							usecard_k(i , pigs[i] . nxt);
							if (!pigs[i] . weapon){
								use_k = false;
							}
							j = 0;
						}
						break;	
					}
					case 'F':{
						if (pigs[i] . ID == 3){
							pigs[i] . cards[j] = 'X';
							getenemy(i , 1);
							if (usecard_j(i , 1 , 0)) break;
							usecard_f(i , 1);
							j = 0;
						}else{
							int to = pigs[i] . nxt;
							while (true){
								if (enemy(i , to)){
									pigs[i] . cards[j] = 'X';
									getenemy(i , to);
									if (usecard_j(i , to , 0)) break;
									usecard_f(i , to);
									j = 0;
									break;
								}
								to = pigs[to] . nxt;
								if (to == i) break;
							}
						}
						break;
					}
					case 'N':{
						pigs[i] . cards[j] = 'X';
						usecard_n(i , pigs[i] . nxt);
						j = 0;
						break;
					}
					case 'W':{
						pigs[i] . cards[j] = 'X';
						usecard_w(i , pigs[i] . nxt);
						j = 0;
						break;
					}
					case 'Z':{
						pigs[i] . cards[j] = 'X';
						pigs[i] . weapon = true;
						use_k = true;
						j = 0;
						break;
					}
				}
				while (pigs[i] . cards[pigs[i] . tot_cards] == 'X') pigs[i] . tot_cards --;
			}
		}
	}
}
bool enemy(int x , int y){
	if (pigs[x] . ID == 1 && pigs[y] . special == true) return true;	
	if (pigs[y] . pigid == 0) return false;
	if (pigs[x] . ID != 3 && pigs[y] . pigid == 3) return true;
	if (pigs[x] . ID == 3 && pigs[y] . pigid != 3) return true;
	return false;
}
bool friendly(int x , int y){
	if (pigs[y] . pigid == 0) return false;
	if (pigs[x] . ID != 3 && pigs[y] . pigid != 3) return true;
	if (pigs[x] . ID == 3 && pigs[y] . pigid == 3) return true;
	return false;	
}
void printcard(int i){
	bool first = true;
	for (int j = 1 ; j <= pigs[i] . tot_cards ; j ++){ 
		if (pigs[i] . cards[j] == 'X') continue;
		if (!first){
			cout << " ";
		}else first = false;
		putchar (pigs[i] . cards[j]);
	}
	putchar (endl);
}
void getcard(int i){
	if (top > m) top = m;
	pigs[i] . tot_cards ++;
	pigs[i] . cards[pigs[i] . tot_cards] = cards[top];
	top ++;
}
int findcard(int x , char cards){
	for (int i = 1 ; i <= pigs[x] . tot_cards ; i ++){
		if (pigs[x] . cards[i] == cards){
			pigs[x] . cards[i] = 'X';
			return true;
		}
	}
	return false;
}
void getfriend(int x , int y){
	if (pigs[y].pigid == 0) return;
	if (pigs[y].pigid != 3) pigs[x] . special = false , pigs[x] . pigid = 1;
	if (pigs[y].pigid == 3) pigs[x] . special = true , pigs[x] . pigid = 3;
}
void getenemy(int x , int y){
	if (pigs[y].pigid == 0) return;
	if (pigs[y].pigid != 3) pigs[x] . pigid = 3 , pigs[x] . special = true;
	if (pigs[y].pigid == 3) pigs[x] . pigid = 1 , pigs[x] . special = false;
}
void dechp(int x , int i){
	pigs[i] . HP --;
	while (pigs[i] . HP <= 0 && findcard(i , 'P')){
		pigs[i] . HP ++;
	}
	if (pigs[i] . HP <= 0){
		pigs[i] . tot_cards = 0;
		pigs[i] . weapon = false;
		if (pigs[i] . ID == 1){
			gameover = true;
			return;
		}else if (pigs[i] . ID == 2){
			if (pigs[x] . ID == 1){
				pigs[x] . tot_cards = 0;
				pigs[x] . weapon = false;
			}
		}else if (pigs[i] . ID == 3){
			FPcnt --;
			if (FPcnt == 0){
				gameover = true;
				return;
			}
			getcard(x); getcard(x); getcard(x);
		}
		pigs[pigs[i] . nxt] . pre = pigs[i] . pre;
	}
}
bool usecard_j(int from , int to , int last){
	int now = from;
	while (true){
		if ((last == 0 && friendly(now , to)) || (last != 0 && enemy(now , last))){
			if (findcard(now , 'J')){
				if (last == 0 && friendly(now , to)) getfriend(now , to);
				if (last != 0 && enemy(now , last)) getenemy(now , last);
				if (!usecard_j(pigs[now] . nxt , to , now)){
					return true;
				}
			}
		}
		now = pigs[now] . nxt;
		if (now == from) return false;
	}
}
void usecard_k(int from , int to){
	getenemy(from , to);
	bool p = findcard(to ,  'D');
	if (p == false){
		dechp(from , to);
	}
}
求条

回复

6 条回复,欢迎继续交流。

正在加载回复...