社区讨论

无无懈可击版本求调 sub3 TLE

P2482[SDOI2010] 猪国杀参与者 1已保存回复 0

讨论操作

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

当前回复
0 条
当前快照
1 份
快照标识符
@lo24rnzf
此快照首次捕获于
2023/10/23 07:59
2 年前
此快照最后确认于
2023/11/03 08:17
2 年前
查看原帖
CPP
// Problem: P2482 [SDOI2010] 猪国杀
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P2482
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;
#define mem(l,val) memset((l),(val),(sizeof(l)))
using namespace std;
const int INF = 0x3f3f3f3f;
char pig[15][4005]; //手牌
queue <char> card; //牌堆
string op[15]; //身份
int hp[15],n,m,tmp,down[15],tmp1[4005],tmp2[4005]; //血量 牌的下标 决斗临时数组
bool die[15],worse[15],bad[15],good[15],used[15],god[15]; //死亡标志 类反猪标志 跳反标志 跳忠标志 用没用过杀 有没有武器
char x; //temp
inline void take(int x,int num) //摸num张牌
{
    while(num--)
    {
        pig[x][++down[x]] = card.front();
        if(card.size() != 1) card.pop();
    }
}
inline int check() //判断游戏是否结束 0是未结束 1是结束且主猪胜利 2是结束且反猪胜利
{
    if(die[1]) return 2;
    for(int i = 2;i <= n;++i)
        if(!die[i] && op[i][0] == 'F') return 0;
    return 1;
}
inline auto write(int res) //根据结果输出
{
    if(res == 1) puts("MP");
    else puts("FP");
    for(int i = 1;i <= n;++i)
    {
        if(die[i]) {puts("DEAD");continue;}
        for(int j = 1;j <= down[i];++j)
            if(pig[i][j] != '0') printf("%c ",pig[i][j]);
        puts("");
    } 
    exit(0);
}
inline void moribund(int a,int b) //a使b濒死
{
    for(int i = 1;i <= down[b];++i)
        if(pig[b][i] == 'P') {pig[b][i] = '0';++hp[b];return;}
    die[b] = 1;
    if(check()) write(check());
    if(op[b][0] == 'F') take(a,3);
    if(op[b][0] == 'Z' && op[a][0] == 'M')
    {
        god[a] = 0;
        for(int i = 1;i <= down[a];++i) pig[a][i] = '0';
        down[a] = 0;
    }
}
inline void Kill(int a,int b) //第a只猪杀第b只猪
{
    for(int i = 1;i <= down[b];++i)
        if(pig[b][i] == 'D') {pig[b][i] = '0';return;}
    --hp[b];
    if(hp[b] <= 0) moribund(a,b);
}
inline void duel(int a,int b) //a对b使用决斗
{
    if((op[a][0] == 'M' && op[b][0] == 'Z')) {--hp[b];return;}
    int cnt1 = 0,cnt2 = 0;
    mem(tmp1,0),mem(tmp2,0);
    for(int i = 1;i <= down[a];++i)
        if(pig[a][i] == 'K') tmp1[++cnt1] = i;
    for(int i = 1;i <= down[b];++i)
        if(pig[b][i] == 'K') tmp2[++cnt2] = i;
    if(cnt1 >= cnt2) 
    {
        --hp[b];
        for(int i = 1;i <= cnt2;++i) 
			pig[a][tmp1[i]] = pig[b][tmp2[i]] = '0';
        if(hp[b] <= 0) moribund(a,b);
    }
    else
    {
        --hp[a];
        for(int i = 1;i <= cnt1;++i)
            pig[a][tmp1[i]] = pig[b][tmp2[i]] = '0';   
        if(hp[a] <= 0) moribund(b,a);   
    }
}
inline void every(int x,char cd)//除x外,每个人出cd
{
    int flag = 0;
    for(int i = x+1;i <= n;++i)
    {
    	if(die[i]) continue;
    	for(int j = 1;j <= down[i];++j)
            if(pig[i][j] == cd)
            {
                pig[i][j] = '0';
                flag = 1;
                break;
            }
        if(!flag)
        {
        	--hp[i];
        	if(hp[i] <= 0) moribund(x,i);
		}
		flag = 0;
	}
	int flag2 = 0;
    for(int i = 1;i <= x-1;++i)
    {
    	if(die[i]) continue;
    	for(int j = 1;j <= down[i];++j)
            if(pig[i][j] == cd)
            {
                pig[i][j] = '0';
                flag2 = 1;
                break;
            }
        if(!flag2)
        {
        	--hp[i];
        	if(hp[i] <= 0) moribund(x,i);
		}
		flag2 = 0;
	}
}
inline void show(int x,int y) //打第x只猪的第y张牌,即pig[x][y]
{
    if(pig[x][y] == 'P' && hp[x] < 4) {++hp[x];pig[x][y] = '0';}
    if(pig[x][y] == 'Z') 
    {
    	god[x] = 1;
    	pig[x][y] = '0';
    	for(int i = 1;i <= y-1;++i)
    		if(pig[x][i] != '0' && !die[x]) show(x,i);
    }
    if(pig[x][y] == 'K' && (!used[x] || god[x]))
    {
        int goal = x+1;
        if(goal > n) goal %= n;
       	while(die[goal])
       	{
       		++goal;
       		if(goal > n) goal %= n;
       	}
        if(op[x][0] == 'M' && (bad[goal] || (worse[goal] && !good[goal])))
            used[x] = 1,pig[x][y] = '0',Kill(x,goal);
        if(op[x][0] == 'Z' && bad[goal])
        {
        	used[x] = 1,pig[x][y] = '0',good[x] = 1,Kill(x,goal);
        	for(int i = 1;i <= y-1;++i)
    			if(pig[x][i] != '0' && !die[x]) show(x,i);
        }
        if(op[x][0] == 'F' && good[goal])
        {
        	used[x] = 1,pig[x][y] = '0',bad[x] = 1,Kill(x,goal);
        	for(int i = 1;i <= y-1;++i)
    			if(pig[x][i] != '0' && !die[x]) show(x,i);
        }
    }
    if(pig[x][y] == 'F')
    {
        for(int i = x+1;i <= n;++i)
        { 
        	if(die[i]) continue;
            if(op[x][0] == 'M' && (bad[i] || (worse[i] && !good[i])))
                pig[x][y] = '0',duel(x,i);
            if(op[x][0] == 'Z' && bad[i])
            {
                pig[x][y] = '0',good[x] = 1,duel(x,i);
                for(int i = 1;i <= y-1;++i)
    				if(pig[x][i] != '0' && !die[x]) show(x,i);
    		}
            if(op[x][0] == 'F' && good[i])
            {
                pig[x][y] = '0',bad[x] = 1,duel(x,i);
                for(int i = 1;i <= y-1;++i)
    				if(pig[x][i] != '0' && !die[x]) show(x,i);
    		}
        }
        if(pig[x][y] == '0') return;
        for(int i = 1;i <= x-1;++i)
        {
        	if(die[i]) continue;
            if(op[x][0] == 'M' && (bad[i] || (worse[i] && !good[i])))
                pig[x][y] = '0',duel(x,i);
            if(op[x][0] == 'Z' && bad[i])
            {
                pig[x][y] = '0',good[x] = 1,duel(x,i);
                for(int i = 1;i <= y-1;++i)
    				if(pig[x][i] != '0' && !die[x]) show(x,i);
    		}
            if(op[x][0] == 'F' && good[i])
            {
                pig[x][y] = '0',bad[x] = 1,duel(x,i);
                for(int i = 1;i <= y-1;++i)
    				if(pig[x][i] != '0' && !die[x]) show(x,i);
    		}
        }
    }
    if(pig[x][y] == 'N') pig[x][y] = '0',every(x,'K');
    if(pig[x][y] == 'W') pig[x][y] = '0',every(x,'D');
}
int main(int argc,char *argv[])
{
    //freopen("data.ans","r",stdin);
    //freopen("data.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i = 1;i <= n;++i) hp[i] = 4;
    good[1] = 1;
    for(int i = 1;i <= n;++i)
        for(int j = 0;j < 4005;++j) pig[i][j] = '0';
    for(int i = 1;i <= n;++i)
    {
        cin>>op[i];
        for(int j = 0;j < 4;++j) cin>>pig[i][++down[i]];
    }
    for(int i = 1;i <= m;++i) {cin>>x;card.push(x);}
    int now = 1; //当前是哪只猪行动
    for(;;)
    {
    	if(die[now]) continue;
        used[now] = 0;
        take(now,2);
        for(int i = 1;i <= down[now];++i)
            if(pig[now][i] != '0' && !die[now]) show(now,i);
        ++now;
       	if(now > n) now %= n;
    }
            
    return 0;
}

回复

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

正在加载回复...