当前位置:网站首页>洛谷P2482 [SDOI2010]猪国杀
洛谷P2482 [SDOI2010]猪国杀
2022-07-07 07:09:00 【moyangxian】
#include<bits/stdc++.h>
using namespace std;
const int N = 20;
vector<char> P;//牌堆
int n, m, f;
int nxt[N], lst[N];
struct Pig {
string name;//真实身份
/* 主猪:MP 忠猪:ZP 反猪:FP */
vector<char> p;
int hp;//血量
int z;//是否装连弩
int t;//表面身份
/* 未知:0 忠猪:1(主猪开始就默认是忠猪) 反猪:2 类反猪:3 */
void throwcard(int& x) {
//丢弃第x张牌
p.erase(p.begin() + x);
x--;
}
int search(char c) {
//找第一张为c的牌,并弃掉
for (int i = 0; i < p.size(); i++) {
if (p[i] == c) {
throwcard(i);
return 1;//找到返回1
}
}
return 0;//找不到返回0
}
void getcard(int x) {
//从牌堆里摸x张牌
while (x--) {
char c = P.front();
p.push_back(c);
P.erase(P.begin());
if (P.empty()) P.push_back(c);
//如果牌堆里牌不够用,则要一直摸最后一张牌
}
}
}a[N];
//游戏结束
void end() {
if (a[1].hp == 0) cout << "FP" << endl;
else cout << "MP" << endl;
for (int i = 1; i <= n; i++) {
if (a[i].hp == 0) cout << "DEAD" << endl;
else {
int len = a[i].p.size();
for (int j = 0; j < len; j++)
cout << a[i].p[j] << " ";
cout << endl;
}
}
exit(0);
}
//判断x能否对y表敌意
int hostility(int x, int y) {
//x是主猪且y是反猪或类反猪
if (a[x].name == "MP" && (a[y].t == 2 || a[y].t == 3))
return 1;
//x是忠猪且y是反猪
if (a[x].name == "ZP" && a[y].t == 2)
return 1;
//x是反猪且y是忠猪
if (a[x].name == "FP" && a[y].t == 1)
return 1;
return 0;
}
//判断x能否对y献殷勤
int squire(int x, int y) {
//x是主猪且y是忠猪
if (a[x].name == "MP" && a[y].t == 1)
return 1;
//x是忠猪且y是忠猪
if (a[x].name == "ZP" && a[y].t == 1)
return 1;
//x是反猪且y是反猪
if (a[x].name == "FP" && a[y].t == 2)
return 1;
return 0;
}
//x杀死了y
void killed(int x, int y) {
if (a[y].name == "MP") end();//判断y是不是主猪
if (a[y].name == "FP") {
f--;
if (f == 0) end();//没有反猪了游戏结束
a[x].getcard(3);//摸三张牌
}
else if (a[y].name == "ZP" && a[x].name == "MP") {
//如果主猪杀掉了忠猪
a[x].p.clear();//清空主猪牌库
a[x].z = 0;//武器也要清空
}
nxt[lst[y]] = nxt[y];
lst[nxt[y]] = lst[y];
}
//x为伤害来源攻击y
void attack(int x, int y) {
a[y].hp--;
if (a[y].hp == 0) {
//血量为0
int t = a[y].search('P');//找桃吃
if (t == 0) killed(x, y);
else a[y].hp++;
}
}
//无懈可击,成功返回1,失败返回0
int Impeccable(int s, int x) {
for (int i = s, j = 0; !j || i != s; i = nxt[i], j = 1) {
int t;
if (x == 0) t = hostility(i, s);
else t = squire(i, x);
//如果x为0说明s是上一次使用无懈可击,否则说明s对x使用
if (t && a[i].search('J')) {
if (a[i].name == "FP") a[i].t = 2;
else a[i].t = 1;
return !Impeccable(i, 0);
}
}
return 0;
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
string s;
cin >> s;
a[i].name = s;
if (s[0] == 'F') f++;
for (int j = 0; j < 4; j++) {
char c;
cin >> c;
a[i].p.push_back(c);
}
nxt[i] = i + 1, lst[i] = i - 1;
a[i].hp = 4;
a[i].z = a[i].t = 0;
}
for (int i = 0; i < m; i++) {
char c;
cin >> c;
P.push_back(c);
}
nxt[n] = 1, lst[1] = n;
int now = 1;
a[1].t = 1;//主猪开始默认为忠猪
if (f == 0) end();
while (true) {
int kill = 0;//是否使用过杀
a[now].getcard(2);//摸两张牌
for (int i = 0; i < a[now].p.size() && a[now].hp; i++) {
if (a[now].p[i] == 'Z') {
//连弩
a[now].z = 1;
a[now].throwcard(i);
i = -1;//要从头开始,因为可能可以使用之前的杀
}
else if (a[now].p[i] == 'P') {
//桃
if (a[now].hp == 4) continue;//满血不用吃
a[now].hp++;
a[now].throwcard(i);
}
else if (a[now].p[i] == 'K') {
if (a[now].z || kill == 0) {
//如果装备了连弩或者没用过杀
int t = nxt[now];//now的下一个猪
if (hostility(now, t)) {
//判断是否能表敌意
if (a[now].name == "FP") a[now].t = 2;
else a[now].t = 1;
a[now].throwcard(i);
kill = 1;
if (!a[t].search('D')) attack(now, t);
}
}
}
else if (a[now].p[i] == 'F') {
//决斗
int j;
if (a[now].name == "FP") j = 1;//反猪决斗对主猪使用
else j = nxt[now];
for (; j != now; j = nxt[j]) {
if (hostility(now, j)) {
a[now].throwcard(i);
if (a[now].name == "FP") a[now].t = 2;
else a[now].t = 1;
if (Impeccable(now, j)) break;
if (a[j].name == "ZP" && a[now].name == "MP") {
attack(now, j);
break;
}
int t = 1;
while (true) {
if (t & 1) {
if (!a[j].search('K')) {
attack(now, j);
break;
}
}
else {
if (!a[now].search('K')) {
attack(j, now);
i = max(-1, i - 1);
break;
}
}
t ^= 1;
}
i = -1;
//决斗可能会让一些猪明确身份,要从头开始枚举牌
break;
}
}
}
else if (a[now].p[i] == 'N' || a[now].p[i] == 'W') {
char c = a[now].p[i], d;
if (c == 'N') d = 'K';
else d = 'D';
a[now].throwcard(i);
for (int j = nxt[now]; j != now; j = nxt[j]) {
if (!Impeccable(now, j) && !a[j].search(d)) {
//攻击了主猪,成为类反猪
if (a[j].name == "MP" && a[now].t == 0) a[now].t = 3;
attack(now, j);
}
}
i = -1;
}
}
now = nxt[now];
}
return 0;
}
/* 2 1 MP K K D J FP W N D N K 3 5 MP F K D J FP J F Z K FP Z W Z P J N P N N */
边栏推荐
猜你喜欢
STM32 and motor development (from stand-alone version to Networking)
信息安全实验四:Ip包监视程序实现
基于智慧城市与储住分离数字家居模式垃圾处理方法
4、 Fundamentals of machine learning
JS reverse tutorial second issue - Ape anthropology first question
[bw16 application] Anxin can realize mqtt communication with bw16 module / development board at instruction
农牧业未来发展蓝图--垂直农业+人造肉
csdn涨薪技术-浅学Jmeter的几个常用的逻辑控制器使用
Lesson 1: finding the minimum of a matrix
[4G/5G/6G专题基础-147]: 6G总体愿景与潜在关键技术白皮书解读-2-6G发展的宏观驱动力
随机推荐
Huawei HCIP - datacom - Core 03 jours
What development models did you know during the interview? Just read this one
用flinksql的方式 写进 sr的表,发现需要删除的数据没有删除,参照文档https://do
如何成为一名高级数字 IC 设计工程师(5-2)理论篇:ULP 低功耗设计技术精讲(上)
csdn涨薪技术-浅学Jmeter的几个常用的逻辑控制器使用
liunx命令
asp. How to call vb DLL function in net project
How to solve the problem of golang select mechanism and timeout
在EXCEL写VBA连接ORACLE并查询数据库中的内容
Database multi table Association query problem
NATAPP内网穿透
小程序弹出半角遮罩层
Sqlplus garbled code problem, find the solution
Unity uses mesh to realize real-time point cloud (I)
Regular matching starts with XXX and ends with XXX
[4g/5g/6g topic foundation -147]: Interpretation of the white paper on 6G's overall vision and potential key technologies -2-6g's macro driving force for development
数据建模中利用3σ剔除异常值进行数据清洗
Difference between process and thread
HCIP 第一天 笔记整理
How to use clipboard JS library implements copy and cut function