社区讨论
无无懈可击版本求调 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 条回复,欢迎继续交流。
正在加载回复...