程序员的资源宝库

网站首页 > gitee 正文

SDOI2010 猪国杀

sanyeah 2024-03-30 13:01:49 gitee 13 ℃ 0 评论

题目传送门

最近题荒,不知道做什么题,就心血来潮挖了一个大坑

一堆猪玩《猪国杀》,想想就\(interesting\)

最终万分艰难的\(A\)掉了, 留贴纪念


坑点

这道题,嗯……,可以说,全是坑点……

  1. 如果牌堆没牌了,那么会一直摸最后一张牌
  2. 距离的意思其实是:每只猪只能杀到他逆时针方向的第一只存活的猪
  3. 主猪杀死忠臣后一定要把牌弃的的干干净净,不要忘了诸葛连弩
  4. 出无懈可击和杀以及决斗都会暴露身份
  5. 反猪只会和主猪决斗
  6. 无懈可击一定要注意,只会给跳身份的人用
  7. 主公默认已跳身份

其他的还有一堆的坑点,写的时候一定要注意

调试方法

可以做一个解说器,输出游戏过程,然后下载\(LOJ\)上的数据,与\(AC\)代码比较输出的过程,效果十分不错

解说器示例:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#define LL long long
using namespace std;
LL read() {
    LL k = 0, f = 1; char c = getchar();
    while(c < '0' || c > '9') {
        if(c == '-') f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9')
      k = k * 10 + c - 48, c = getchar();
    return k * f;
}
char read_c() {
	char c = getchar();
	while ((c < 'a' || c > 'b') && (c < 'A' || c > 'Z')) c = getchar();
	while ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) return c;
	return c;
}
int n, m;
struct zzz {
	int tot, hp, dis, id;  // 手牌数量  血量  距离  身份:1=mp 2=zp 3=fp
	bool lfz, zgln, wszd, dead, one; // 类反猪标志  诸葛连弩  表明身份  死亡 杀只能用一次
	char  cord[2010]; // 手牌
}pig[110];
char allc[2010]; int pos;
int fp_num;
void mopai(int num, int k) {
	int &tot = pig[num].tot;
	for(int i = 1; i <= k; ++i) {
		if(pos == m) --pos;
		pig[num].cord[++tot] = allc[++pos];
	}
}
bool waf(int x, int y) {  // 判断x是否会对y献殷勤
	zzz &px = pig[x], &py = pig[y];
	if(py.wszd && (px.id == py.id || (px.id == 2 && py.id == 1) || (px.id == 1 && py.id == 2))) return 1;
	return 0;
}
bool godie(int x, int y){ //  判断x是否会对y表敌意
	zzz &px = pig[x], &py = pig[y];
	if(py.wszd && (px.id == 2 || px.id == 1) && py.id == 3) return 1;
	if(py.wszd && px.id == 3 && (py.id == 1 || py.id == 2)) return 1;
	if(py.lfz && px.id == 1) return 1;
	return 0;
}
bool wxkj(int num, int k, int lx) {
	for(int i = num, ii = 1; ii <= n; i = i%n+1, ++ii) {
		if(!lx && waf(i, k)) {
			for(int j = 1; j <= pig[i].tot; ++j) {
				if(pig[i].cord[j] == 'J') {
					printf("玩家%d使用了无懈可击\n" ,i);
					pig[i].wszd = 1, pig[i].cord[j] = '*', pig[i].lfz = 0;
					//if(pig[2].wszd) printf("2号猪暴露身份\n\n");
					int cnt = i%n+1;
					if(wxkj(cnt, k, lx^1)) return 0; else return 1;
				}
			}
		}
		if(lx && godie(i, k)) {
			for(int j = 1; j <= pig[i].tot; ++j) {
				if(pig[i].cord[j] == 'J') {
					printf("玩家%d使用了无懈可击\n" ,i);
					pig[i].wszd = 1, pig[i].cord[j] = '*', pig[i].lfz = 0;
					int cnt = i%n+1;
					if(wxkj(cnt, k, lx^1)) return 0; else return 1;
				}
			}
		}

	}
	return 0;
}
void gameover(int flag) {
	printf("游戏结束\n");
	if(flag == 1) puts("MP");
	else puts("FP");
	for(int i = 1; i <= n; ++i) {
		if(pig[i].dead) {
			puts("DEAD"); continue;
		}
		for(int j = 1; j <= pig[i].tot; ++j) {
			if(pig[i].cord[j] != '*') printf("%c ", pig[i].cord[j]);
		}
		printf("\n");
	}
	exit(0);
}
void die(int num, int vic) { // num 伤害来源, vic 濒死
	zzz &p = pig[vic];
	for(int i = 1; i <= p.tot; ++i) {
		if(p.cord[i] == 'P') {
			printf("玩家%d对自己使用了桃,回复了一滴血\n", vic);
			p.cord[i] = '*', ++p.hp; return ;
		}
	}
	printf("玩家%d死亡,击杀者为玩家%d\n", vic, num);
	p.dead = 1;
	for(int i = 1; i <= p.tot; ++i) p.cord[i] = '*';
	if(p.id == 1) gameover(2); // 反猪胜利
	if(p.id == 3) {
		--fp_num; if(!fp_num) gameover(1); //主猪胜利
		mopai(num, 3);
		printf("玩家%d杀死了反贼,抽三张牌\n",num);
	}
	if(p.id == 2 && pig[num].id == 1) {
		for(int i = 1; i <= pig[num].tot; ++i)
			pig[num].cord[i] = '*';
		pig[num].zgln = 0;
		printf("主公杀死了忠臣,弃掉所有手牌\n");
	}
	int ff = 0, fff = 0;
	for(int i = n; i >= 1; --i) {
		if(!pig[i].dead) pig[i].dis = ff;
		if(!fff && !pig[i].dead) fff = i;
		ff = i;
	}
	pig[fff].dis = 1;
}
bool jd(int x, int y) {
	zzz &px = pig[x], &py = pig[y];
	int xx = 0, yy = 0;
	for(int i = 1; i <= px.tot; ++i)
		if(px.cord[i] == 'K') ++xx;
	for(int i = 1; i <= py.tot; ++i)
		if(py.cord[i] == 'K') ++yy;
	if(xx >= yy) {
		for(int i = 1, num = 1; num <= yy; ++i)
			if(px.cord[i] == 'K') px.cord[i] ='*', ++num;
		for(int i = 1, num = 1; num <= yy; ++i)
			if(py.cord[i] == 'K') py.cord[i] ='*', ++num;
		return 1;
	}
	else {
		for(int i = 1, num = 1; num <= xx; ++i)
			if(px.cord[i] == 'K') px.cord[i] ='*', ++num;
		for(int i = 1, num = 1; num <= xx+1; ++i)
			if(py.cord[i] == 'K') py.cord[i] ='*', ++num;
		return 0;
	}
}
bool chupai(int num) {
	zzz &p = pig[num];
	//if(p.cord[p.pos] == '*') ++p.pos;
	for(int l = 1; l <= p.tot; ++l) {
		if(p.cord[l] == 'Z') {
			printf("玩家%d装备了诸葛连弩\n", num);
			p.cord[l] = '*', p.zgln = 1; return 1;
		}
		if(p.cord[l] == 'P' && p.hp < 4) {
			printf("玩家%d 对自己使用了桃 ,现在剩余体力值为%d点\n ", num, pig[num].hp);
			p.cord[l] = '*', ++p.hp; return 1;
		}
		// W N 联动
		if(p.cord[l] == 'N') {
			printf("玩家%d对全体玩家使用了南蛮入侵\n", num);
			int cnt = num % n + 1; p.cord[l] = '*';
			for(int i = cnt; i != num; i = i%n+1) {
				if(pig[i].dead) continue; bool flag = 0;
				
				if(pig[i].wszd)  // 只能对跳身份的人献殷勤
					if(wxkj(num, i, 0)) flag = 1;
				if(flag) continue;
				else printf("没有人对玩家%d使用无懈可击\n", i);
				
				for(int j = 1; j <= pig[i].tot; ++j) {
					if(pig[i].cord[j] == 'K') {
						printf("玩家%d使用了一张杀\n", i);
						pig[i].cord[j] = '*', flag = 1; break;
					}
				}
				if(!flag) {
					printf("玩家%d失去了一点体力\n", i);
					--pig[i].hp;
					if(pig[i].hp) printf("玩家%d的血量是 %d\n", i, pig[i].hp);
					if(i == 1 && !p.wszd) p.lfz = 1;
				}
				if(!pig[i].hp) die(num, i);
			}
			return 1;
		}
		if(p.cord[l] == 'W') {
			printf("玩家%d对全体玩家使用了万箭齐发\n", num);
			int cnt = num % n + 1; p.cord[l] = '*';
			for(int i = cnt; i != num; i = i%n+1) {
				if(pig[i].dead) continue;
				bool flag = 0;

				if(pig[i].wszd)  // 只能对跳身份的人献殷勤
					if(wxkj(num, i, 0)) flag = 1;
				if(flag) continue;
				else printf("没有人对玩家%d使用无懈可击\n", i);

				for(int j = 1; j <= pig[i].tot; ++j) {
					if(pig[i].cord[j] == 'D') {
						printf("玩家%d使用了一张闪\n", i);
						pig[i].cord[j] = '*', flag = 1; break;
					}
				}
				if(!flag) {
					printf("玩家%d失去了一点体力\n", i);
					--pig[i].hp;
					if(pig[i].hp) printf("玩家%d的血量是 %d\n", i, pig[i].hp);
					if(i == 1 && !p.wszd) p.lfz = 1;
				}
				if(!pig[i].hp) die(num, i);
			}
			return 1;
		}

		if(p.cord[l] == 'K') {
			if(p.one && !p.zgln) return 0;
			bool flag = 0;
			int i = p.dis;
			if(!pig[i].dead && godie(num, i)) {
				printf("玩家%d对玩家%d使用了一张杀\n", num, i);
				p.cord[l] = '*'; p.wszd = 1; p.one = 1; p.lfz = 0;
				for(int j = 1; j <= pig[i].tot; ++j) {
					if(pig[i].cord[j] == 'D') {
						printf("玩家%d使用了一张闪\n", i);
						pig[i].cord[j] = '*', flag = 1; break;
					}
				}
				if(!flag) printf("玩家%d 受到了来自 玩家%d的杀的伤害\n", i, num), --pig[i].hp;
				if(pig[i].hp) printf("玩家%d的血量是 %d\n", i, pig[i].hp);
				if(!pig[i].hp) die(num, i);
				return 1;
				break;
			}
		}

		if(p.cord[l] == 'F') {
			int cnt = num % n + 1;
			if(p.id == 3) {
				int i = 1;
				printf("玩家%d对玩家%d使用了一张决斗\n", num, i);
				p.cord[l] = '*'; p.wszd = 1; p.lfz = 0;
				if(pig[i].wszd && wxkj(num, i, 0)) break;
				if(p.id == 1 && pig[i].lfz == 1 && pig[i].id == 2) {
					printf("玩家%d决斗失败,失去一点血\n", i); --pig[i].hp; goto ree;
				}
				if(jd(num, i)) --pig[i].hp, printf("玩家%d决斗失败,失去一点血\n",i);
				else --pig[num].hp, printf("玩家%d决斗失败,失去一点血\n", num);
				ree:
				if(pig[num].hp) printf("玩家%d的血量是 %d\n", num,pig[num].hp);
				if(pig[i].hp) printf("玩家%d的血量是 %d\n", i,pig[i].hp);

				if(!pig[i].hp) die(num, i);
				if(!pig[num].hp) die(i, num);
				return 1;
			}
			for(int i = cnt; i != num; i = i%n+1) {
				if(!pig[i].dead && godie(num, i)) {
					printf("玩家%d对玩家%d使用了一张决斗\n", num, i);
					p.cord[l] = '*'; p.wszd = 1; p.lfz = 0;
					if(wxkj(num, i, 0)) break;
					if(p.id == 1 && pig[i].lfz == 1 && pig[i].id == 2) {
						printf("玩家%d决斗失败,失去一点血\n", i);
						--pig[i].hp; goto re;
					}
					if(jd(num, i)) --pig[i].hp, printf("玩家%d决斗失败,失去一点血\n",i);
					else --pig[num].hp, printf("玩家%d决斗失败,失去一点血\n", num);
					re:
					if(pig[num].hp) printf("玩家%d的血量是 %d\n", num,pig[num].hp);
					if(pig[i].hp) printf("玩家%d的血量是 %d\n", i,pig[i].hp);

					if(!pig[i].hp) die(num, i);
					if(!pig[num].hp) die(i, num);
					return 1;
				}
			}
		}
	}
	return 0;
}
int main() {
	freopen("1.in", "r", stdin);
	freopen("my.out", "w", stdout);
	n = read(), m = read();
	for(int i = 1; i <= n; ++i) {
		char c[3]; cin >> c;
		pig[i].hp = pig[i].tot = 4;
		if(c[0] == 'M') pig[i].id = 1;
		if(c[0] == 'Z') pig[i].id = 2;
		if(c[0] == 'F') pig[i].id = 3, ++fp_num;
		for(int j = 1; j <= 4; ++j) pig[i].cord[j] = read_c();
		pig[i].dis = i % n + 1;
	}
	pig[1].wszd = 1;
	for(int i = 1; i <= m; ++i) allc[i] = read_c();
	int cnt = 0, tot = 0;
	while(1) {
		cnt = cnt % n + 1;  zzz &p = pig[cnt];
		if(p.dead) continue;
		mopai(cnt, 2);
		while(chupai(cnt)) {}
		p.one = 0;
		printf("回合%d结束\n", ++tot); printf("\n----------------------\n\n");
	}
	return 0;
}

AC代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#define LL long long
using namespace std;
LL read() {
    LL k = 0, f = 1; char c = getchar();
    while(c < '0' || c > '9') {
        if(c == '-') f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9')
      k = k * 10 + c - 48, c = getchar();
    return k * f;
}
char read_c() {
    char c = getchar();
    while ((c < 'a' || c > 'b') && (c < 'A' || c > 'Z')) c = getchar();
    while ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) return c;
    return c;
}
int n, m;
struct zzz {
    int tot, hp, dis, id;  // 手牌数量  血量  距离  身份:1=mp 2=zp 3=fp
    bool lfz, zgln, wszd, dead, one; // 类反猪标志  诸葛连弩  表明身份  死亡 杀只能用一次
    char  cord[2010]; // 手牌
}pig[110];
char allc[2010]; int pos;
int fp_num;
void mopai(int num, int k) {
    int &tot = pig[num].tot;
    for(int i = 1; i <= k; ++i) {
        if(pos == m) --pos;
        pig[num].cord[++tot] = allc[++pos];
    }
}
bool waf(int x, int y) {  // 判断x是否会对y献殷勤
    zzz &px = pig[x], &py = pig[y];
    if(py.wszd && (px.id == py.id || (px.id == 2 && py.id == 1) || (px.id == 1 && py.id == 2))) return 1;
    return 0;
}
bool godie(int x, int y){ //  判断x是否会对y表敌意
    zzz &px = pig[x], &py = pig[y];
    if(py.wszd && (px.id == 2 || px.id == 1) && py.id == 3) return 1;
    if(py.wszd && px.id == 3 && (py.id == 1 || py.id == 2)) return 1;
    if(py.lfz && px.id == 1) return 1;
    return 0;
}
bool wxkj(int num, int k, int lx) {
    for(int i = num, ii = 1; ii <= n; i = i%n+1, ++ii) {
        if(!lx && waf(i, k)) {
            for(int j = 1; j <= pig[i].tot; ++j) {
                if(pig[i].cord[j] == 'J') {
                    pig[i].wszd = 1, pig[i].cord[j] = '*', pig[i].lfz = 0;
                    int cnt = i%n+1;
                    if(wxkj(cnt, k, lx^1)) return 0; else return 1;
                }
            }
        }
        if(lx && godie(i, k)) {
            for(int j = 1; j <= pig[i].tot; ++j) {
                if(pig[i].cord[j] == 'J') {
                    pig[i].wszd = 1, pig[i].cord[j] = '*', pig[i].lfz = 0;
                    int cnt = i%n+1;
                    if(wxkj(cnt, k, lx^1)) return 0; else return 1;
                }
            }
        }

    }
    return 0;
}
void gameover(int flag) {
    if(flag == 1) puts("MP");
    else puts("FP");
    for(int i = 1; i <= n; ++i) {
        if(pig[i].dead) {
            puts("DEAD"); continue;
        }
        for(int j = 1; j <= pig[i].tot; ++j) {
            if(pig[i].cord[j] != '*') printf("%c ", pig[i].cord[j]);
        }
        printf("\n");
    }
    exit(0);
}
void die(int num, int vic) { // num 伤害来源, vic 濒死
    zzz &p = pig[vic];
    for(int i = 1; i <= p.tot; ++i) {
        if(p.cord[i] == 'P') {
            p.cord[i] = '*', ++p.hp; return ;
        }
    }
    p.dead = 1;
    for(int i = 1; i <= p.tot; ++i) p.cord[i] = '*';
    if(p.id == 1) gameover(2); // 反猪胜利
    if(p.id == 3) {
        --fp_num; if(!fp_num) gameover(1); //主猪胜利
        mopai(num, 3);
    }
    if(p.id == 2 && pig[num].id == 1) {
        for(int i = 1; i <= pig[num].tot; ++i)
            pig[num].cord[i] = '*';
        pig[num].zgln = 0;
    }
    int ff = 0, fff = 0;
    for(int i = n; i >= 1; --i) {
        if(!pig[i].dead) pig[i].dis = ff;
        if(!fff && !pig[i].dead) fff = i;
        ff = i;
    }
    pig[fff].dis = 1;
}
bool jd(int x, int y) {
    zzz &px = pig[x], &py = pig[y];
    int xx = 0, yy = 0;
    for(int i = 1; i <= px.tot; ++i)
        if(px.cord[i] == 'K') ++xx;
    for(int i = 1; i <= py.tot; ++i)
        if(py.cord[i] == 'K') ++yy;
    if(xx >= yy) {
        for(int i = 1, num = 1; num <= yy; ++i)
            if(px.cord[i] == 'K') px.cord[i] ='*', ++num;
        for(int i = 1, num = 1; num <= yy; ++i)
            if(py.cord[i] == 'K') py.cord[i] ='*', ++num;
        return 1;
    }
    else {
        for(int i = 1, num = 1; num <= xx; ++i)
            if(px.cord[i] == 'K') px.cord[i] ='*', ++num;
        for(int i = 1, num = 1; num <= xx+1; ++i)
            if(py.cord[i] == 'K') py.cord[i] ='*', ++num;
        return 0;
    }
}
bool chupai(int num) {
    zzz &p = pig[num];
    //if(p.cord[p.pos] == '*') ++p.pos;
    for(int l = 1; l <= p.tot; ++l) {
        if(p.cord[l] == 'Z') {
            p.cord[l] = '*', p.zgln = 1; return 1;
        }
        if(p.cord[l] == 'P' && p.hp < 4) {
            p.cord[l] = '*', ++p.hp; return 1;
        }
        // W N 联动
        if(p.cord[l] == 'N') {
            int cnt = num % n + 1; p.cord[l] = '*';
            for(int i = cnt; i != num; i = i%n+1) {
                if(pig[i].dead) continue; bool flag = 0;
                
                if(pig[i].wszd)  // 只能对跳身份的人献殷勤
                    if(wxkj(num, i, 0)) flag = 1;
                if(flag) continue;
                
                for(int j = 1; j <= pig[i].tot; ++j) {
                    if(pig[i].cord[j] == 'K') {
                        pig[i].cord[j] = '*', flag = 1; break;
                    }
                }
                if(!flag) {
                    --pig[i].hp;
                    if(i == 1 && !p.wszd) p.lfz = 1;
                }
                if(!pig[i].hp) die(num, i);
            }
            return 1;
        }
        if(p.cord[l] == 'W') {
            int cnt = num % n + 1; p.cord[l] = '*';
            for(int i = cnt; i != num; i = i%n+1) {
                if(pig[i].dead) continue;
                bool flag = 0;

                if(pig[i].wszd)  // 只能对跳身份的人献殷勤
                    if(wxkj(num, i, 0)) flag = 1;
                if(flag) continue;

                for(int j = 1; j <= pig[i].tot; ++j) {
                    if(pig[i].cord[j] == 'D') {
                        pig[i].cord[j] = '*', flag = 1; break;
                    }
                }
                if(!flag) {
                    --pig[i].hp;
                    if(i == 1 && !p.wszd) p.lfz = 1;
                }
                if(!pig[i].hp) die(num, i);
            }
            return 1;
        }

        if(p.cord[l] == 'K') {
            if(p.one && !p.zgln) continue;
            bool flag = 0;
            int i = p.dis;
            if(!pig[i].dead && godie(num, i)) {
                p.cord[l] = '*'; p.wszd = 1; p.one = 1; p.lfz = 0;
                for(int j = 1; j <= pig[i].tot; ++j) {
                    if(pig[i].cord[j] == 'D') {
                        pig[i].cord[j] = '*', flag = 1; break;
                    }
                }
                if(!flag) --pig[i].hp;
                if(!pig[i].hp) die(num, i);
                return 1;
                break;
            }
        }

        if(p.cord[l] == 'F') {
            int cnt = num % n + 1;
            if(p.id == 3) {
                int i = 1;
                p.cord[l] = '*'; p.wszd = 1; p.lfz = 0;
                if(pig[i].wszd && wxkj(num, i, 0)) break;
                if(p.id == 1 && pig[i].lfz == 1 && pig[i].id == 2) {
                    --pig[i].hp; goto ree;
                }
                if(jd(num, i)) --pig[i].hp;
                else --pig[num].hp;
                ree:
                if(!pig[i].hp) die(num, i);
                if(!pig[num].hp) die(i, num);
                return 1;
            }
            for(int i = cnt; i != num; i = i%n+1) {
                if(!pig[i].dead && godie(num, i)) {
                    p.cord[l] = '*'; p.wszd = 1; p.lfz = 0;
                    if(wxkj(num, i, 0)) break;
                    if(p.id == 1 && pig[i].lfz == 1 && pig[i].id == 2) {
                        --pig[i].hp; goto re;
                    }
                    if(jd(num, i)) --pig[i].hp;
                    else --pig[num].hp;
                    re:
                    if(!pig[i].hp) die(num, i);
                    if(!pig[num].hp) die(i, num);
                    return 1;
                }
            }
        }
    }
    return 0;
}
int main() {
    n = read(), m = read();
    for(int i = 1; i <= n; ++i) {
        char c[3]; cin >> c;
        pig[i].hp = pig[i].tot = 4;
        if(c[0] == 'M') pig[i].id = 1;
        if(c[0] == 'Z') pig[i].id = 2;
        if(c[0] == 'F') pig[i].id = 3, ++fp_num;
        for(int j = 1; j <= 4; ++j) pig[i].cord[j] = read_c();
        pig[i].dis = i % n + 1;
    }
    pig[1].wszd = 1;
    for(int i = 1; i <= m; ++i) allc[i] = read_c();
    int cnt = 0;
    while(1) {
        cnt = cnt % n + 1;  zzz &p = pig[cnt];
        if(p.dead) continue;
        mopai(cnt, 2);
        while(chupai(cnt)) {}
        p.one = 0;
    }
    return 0;
}

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表