[挑战记录]猪国杀
觉得没有做过猪国杀的人生是不完整的!
于是决定开肝(
先在前面写上需要注意的点
1.找清目标,判断好角色;
2.装上诸葛连弩后,前面的杀也能用;
3.决斗时,进攻发起者可以要使用多张杀,所以要处理好决斗后,手牌剩余部分;
4.决斗时,可能进攻发起者会GG(不知道他怎么想的,不愧是pig),此时要停止他的回合;
5.万箭齐发(南蛮入侵)时,可能会有多人GG,可能会摸多次牌;
6.万箭齐发(南蛮入侵)时,可能会有多人GG,同时发动者是主公,不仅杀死了忠臣,也杀死了反贼,此时也要考虑弃掉所有手牌和摸三张牌的顺序;
7.决斗时,主公认为对面是类反贼,实际上是忠臣,忠臣要牺牲一滴血;
8.在决斗时,发起者会明确身份;在万箭齐发(南蛮入侵)时,可能并不会,但有可能成为类反贼;
9.无懈不可能先手打出,并不代表在自己回合内就不用出无懈;
10.无懈的优先级很高(比一般锦囊牌都高);
11.当一个人使用了无懈,他的身份就完全表明了;
12.无懈看似是最复杂,但是实际上相当于一个补丁(尽管有挺多的细节);
下面还有一些全局的注意点:
13.主公杀死忠臣,一定要把装备给弃了;
14.关于一轮能否出多次杀,要注意判断;
15.一张牌,你出了,就相当于弃置了,不管最后是否生效;
16.最形象的方法存手牌显然是链表,但考虑到实际需要,一般直接开数组(这里我用了维护两个指针,能过)
17.要分清在自己的回合出牌和在别人的回合出牌,最好用不同方法处理,但处理也有很多细节(因人而异);
18.注意主公也会对类反贼表敌意;
19.杀,桃,无懈都是有可能在自己回合打出的“响应牌”(就是回击别人的牌),要注意处理方法(要看清是自己回合还是他人回合出的牌);
20.严格意义上,除了“桃”,在自己回合出了每一张牌后,都可能会激活这张牌前面的牌;
21.注意这里的距离是单向的,而不是双向的,而且恒为 \(1\);
22.存在用无懈无懈掉自己的锦囊牌的情况;
23.阵亡的人已经没有任何价值,直接跳过他;
24.一旦出现胜利局面,就要停止一切操作,但是需要把没有整理好的手牌整理好;
25.对于一个人,要是把手牌扫了一遍,没有出任何牌,就结束出牌;
26.一个人死了后,及时更新上一个玩家的下一个玩家nxt(不必 \(\mathcal{O(1)}\) 求);
27.注意一个人处于濒死状态的处理,每当有一个人死了,都要判断一下游戏是否结束了;
28.当牌堆没有牌时,要一直摸最后一张牌。
2022-09-22 18:45
吃着葡萄欣赏“人走机子开”
开始答题
19:29
看错一次题目(必须从左边开始摸牌)
19:54
又看错一次题目(类反猪和反猪是不同的)
20:03
拉 \(\color{black}{C}\color{red}{reator\_157}\) 大佬入坑
20:09
初步完成 \(K\) 函数构建
20:17
基本完成 \(P\) 函数,以及完善了 \(K\) 函数
20:41
完成 \(F\) 函数,顺便写了不知道有没有用的 \(passive\_kill\)
21:06
\(\color{black}{C}\color{red}{reator\_157}\) 大佬弃坑力(悲
21:38
将先前的函数全部修正,加入死人 \(victim\) 函数和判断胜利 \(victory\) 函数
今日码量: \(158\) 行
09-23
早上跑操加圈(悲)
06:43
完成 \(N\) 函数,\(W\) 函数
06:52
发现大锅需要补(类反猪不会被忠猪攻击)
08:27
开始施工主函数 \(play\)
09:50
交了第一次,TLE0
10:30
发现错误:猪的类型判断出错
反 猪 护 主 猪
11:08
发现一个巨大的锅,交了两次 \(0\)
主要问题在于无限摸牌 \(\cdots\)
14:08
查明主要问题:摸牌的时候上限写成了 \(n\)
\(10\) 分!
14:28
破 \(300\) 行
14:52
完成了一些辅助函数,完善 \(play\) 函数
15:27
决斗函数好像伪了,决斗攻击距离不为 \(1\)
开始大修
16:23
\(15\) 分!
16:51
\(20\) 分!
17:18
眼瞎了,没看见“如果有机会向主猪表敌意”
然后一只反猪就在主公空城 \(+\) 一点血的情况下对着满杀的忠臣用了决斗
乐死了
17:25
\(25\) 分力!
17:38
\(30\) 分!
17:53
发现链表哪里挂了,第二个子任务完成
\(35\) 分!
同时代码达到了 \(10.3K\)
晚上打 \(CF\)
今日码量:\(348\) 行
09-24
上午改题
15:00
开始调题,写 \(J\) 函数
15:46
\(40\) 分!
16:32
《关于一只忠猪出了万箭齐发打了主公这件事》
《关于这只忠猪已经跳忠了这件事》
《关于另外一只忠猪用无懈帮主公挡了,跳忠这件事》
《关于出万箭齐发的忠猪对用无懈的忠猪甩了一张决斗这件事》
好耶
16:36
《关于反猪帮主猪出了张无懈可击这件事》
17:08
原来当前出完牌后可以直接无懈自己,我大意了啊
17:10
\(55\) 分!!!
18:45
吃完晚饭回来写
发现两重循环只跳了一层,我是 \(\operatorname{SB}\)
19:04
\(65\) 分了
19:13
《关于主猪把忠猪给自己的无懈可击无懈掉了这档子事》
19:16
\(90\) 分!!!
19:21
为啥我给死人用了无懈可击?
19:26
\(95\) 分,只差一步!
19:30
\(\mathfrak{AC}\)
385行,12.05KB,100分
#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#define WR WinterRain
#define int long long
using namespace std;
const int WR=10010;
struct Pig{
int opt;//0:主 1:忠 2:反
int pos;//目前状态,true表示忠猪
bool dead,equip,kill;
int nxt;
int HP,l,r;
char card[WR];
bool vis[WR];
}pig[11];
char card[WR];
int n,m;
int l,cntf;
int read(){
int s=0,w=1;
char ch=getchar();
while(ch>'9'||ch<'0'){
if(ch=='-') w=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=(s<<3)+(s<<1)+ch-'0';
ch=getchar();
}
return s*w;
}
void getcard(int id){
if(l!=m) l++;
pig[id].card[++pig[id].r]=card[l];
//cout<<"Pig "<<id<<" get card "<<card[l]<<",l="<<pig[id].l<<",r="<<pig[id].r<<endl;
}
void victory(int opt){
if(opt) printf("FP\n");
else printf("MP\n");
for(int i=1;i<=n;i++){
if(pig[i].dead) printf("DEAD\n");
else{
for(int j=pig[i].l;j<=pig[i].r;j++){
if(!pig[i].vis[j]) printf("%c ",pig[i].card[j]);
}
printf("\n");
}
}
}
bool victim(int frm,int body){
//cout<<body<<" DEAD"<<endl;
if(pig[body].opt==2){
cntf--;
if(!cntf){
victory(0);
return true;
}
getcard(frm);getcard(frm);getcard(frm);
}else if(pig[body].opt==1&&pig[frm].opt==0){
for(int i=pig[frm].l;i<=pig[frm].r;i++) pig[frm].vis[i]=true;
pig[frm].equip=false;
}else if(pig[body].opt==0){
victory(1);
return true;
}
return false;
}
bool flawless(int frm,int id){
if(pig[id].pos==-1) return false;
bool flag=false,vis=true;
//cout<<id<<" flawlessing..."<<endl;
while(vis){
vis=false;
int pos=frm;
do{
if(((pig[id].pos==pig[pos].opt)||(pig[id].pos==0&&pig[pos].opt==1)
||(pig[id].pos==1&&pig[pos].opt==0))^flag){
for(int i=pig[pos].l;i<=pig[pos].r;i++){
if(pig[pos].card[i]=='J'&&(!pig[pos].vis[i])){
//cout<<pos<<" flawlessed"<<endl;
if(pig[pos].pos==-1){
if(flag^(pig[id].pos==2)) pig[pos].pos=2;
else pig[pos].pos=1;
}
pig[pos].vis[i]=true;
flag^=1;vis=true;
while(pig[pos].vis[pig[pos].l]) pig[pos].l++;
break;
}
}
}
while(pig[pig[pos].nxt].dead) pig[pos].nxt=pig[pig[pos].nxt].nxt;
pos=pig[pos].nxt;
if(pos==frm) break;
}while(pos!=frm);
}
//cout<<(flag?"Success":"Failed")<<endl;
return flag;
}
int peach(int id){
//cout<<"Peached "<<id<<endl;
int heal=0;
for(int i=pig[id].l;i<=pig[id].r;i++){
if((!pig[id].vis[i])&&pig[id].card[i]=='P'){
heal++;pig[id].vis[i]=true;
}
if(heal) break;
}
while(pig[id].vis[pig[id].l]) pig[id].l++;
return heal;
}
int save(int frm,int to){
if(peach(to)==0){
pig[to].dead=true;
if(victim(frm,to)) return -1;
else return 1;
}else pig[to].HP=1;
//cout<<to<<" saved itself"<<endl;
return 0;
}
int kill(int frm,int to){//返回0表示被闪掉,1表示掉了血没死,2表示杀死了,-1表示结束了
//cout<<frm<<" killing "<<to<<endl;
if(pig[frm].pos!=0){
if(pig[to].pos==2) pig[frm].pos=1;
else if(pig[to].pos==0||pig[to].pos==1) pig[frm].pos=2;
}
for(int i=pig[to].l;i<=pig[to].r;i++){
if((!pig[to].vis[i])&&pig[to].card[i]=='D'){
pig[to].vis[i]=true;
//cout<<"...failed\n";
return 0;
}
}
pig[to].HP--;
if(!pig[to].HP){
int opt=save(frm,to);
if(opt==-1) return -1;
}
while(pig[to].vis[pig[to].l]) pig[to].l++;
if(pig[to].HP) return 1;
else return 2;
}
int arrow_kill(int frm,int to){//返回0表示被闪掉,1表示掉了血没死,2表示杀死了,-1表示结束了
//cout<<frm<<" arrow_killing "<<to<<endl;
for(int i=pig[to].l;i<=pig[to].r;i++){
if((!pig[to].vis[i])&&pig[to].card[i]=='D'){
pig[to].vis[i]=true;
//cout<<"...failed\n";
return 0;
}
}
pig[to].HP--;
if(!pig[to].HP){
int opt=save(frm,to);
if(opt==-1) return -1;
}
while(pig[to].vis[pig[to].l]) pig[to].l++;
if(pig[to].HP) return 1;
else return 2;
}
bool execute_kill(int pos){
pig[pos].kill=true;
int res=kill(pos,pig[pos].nxt);
if(res==-1) return false;
else if(res==2) pig[pos].nxt=pig[pig[pos].nxt].nxt;
return true;
}
bool passive_kill(int id){
for(int i=pig[id].l;i<=pig[id].r;i++){
if((!pig[id].vis[i])&&pig[id].card[i]=='K'){
pig[id].vis[i]=true;
while(pig[id].vis[pig[id].l]) pig[id].l++;
return true;
}
}
while(pig[id].vis[pig[id].l]) pig[id].l++;
return false;
}
int duel(int frm,int to){
//cout<<frm<<" dueling "<<to<<endl;
if(pig[frm].pos!=0){
if(pig[to].pos==2) pig[frm].pos=1;
else if(pig[to].pos==0||pig[to].pos==1) pig[frm].pos=2;
//cout<<"Pig "<<frm<<" is "<<pig[frm].pos<<endl;
}
if(flawless(frm,to)) return 0;
if(pig[frm].opt==0&&pig[to].opt==1){
pig[to].HP--;
if(!pig[to].HP) return save(frm,to);
else return 0;
}
while(1==1){
if(!passive_kill(to)){
//cout<<to<<" failed"<<endl;
pig[to].HP--;
if(!pig[to].HP) return save(frm,to);
else return 0;
}
if(!passive_kill(frm)){
//cout<<frm<<" failed"<<endl;
pig[frm].HP--;
if(!pig[frm].HP) return save(to,frm)*2;
else return 0;
}
}
}
int execute_duel(int pos,int to){
int res=duel(pos,to);
if(res<0) return 0;
else if(!res) return 1;
else if(res==1){
//cout<<to<<"Dead"<<endl;
int tmp=pig[pos].nxt;
while(pig[tmp].nxt!=to) tmp=pig[tmp].nxt;
pig[tmp].nxt=pig[to].nxt;
return 2;
}else{
//cout<<pos<<"Dead"<<endl;
int tmp=pig[to].nxt;
while(pig[tmp].nxt!=pos) tmp=pig[tmp].nxt;
pig[tmp].nxt=pig[pos].nxt;
return 2;
}
}
int invade(int id){
for(int i=pig[id].nxt;i!=id;i=pig[i].nxt){
if(pig[id].dead) continue;
if(flawless(id,i)) continue;
if(!passive_kill(i)){
pig[i].HP--;
//cout<<i<<"'s HP="<<pig[i].HP<<endl;
if(pig[i].pos==0&&pig[id].pos==-1) pig[id].pos=3;
if(!pig[i].HP&&save(id,i)==-1) return -1;
}
}
return 0;
}
int arrow(int id){
for(int i=pig[id].nxt;i!=id;i=pig[i].nxt){
if(pig[id].dead) continue;
if(flawless(id,i)) continue;
int res=arrow_kill(id,i);
if(res==-1) return -1;
else if(res==1){
if(pig[i].pos==0&&pig[id].pos==-1) pig[id].pos=3;
}
}
return 0;
}
void crossbow(int id){
pig[id].equip=true;
}
void play(){
int pos=1;
while(1==1){
getcard(pos),getcard(pos);
pig[pos].kill=false;
bool opt=true;
while(opt){
if(pig[pos].dead) break;
opt=false;
for(int i=pig[pos].l;i<=pig[pos].r;i++){
//cout<<"Pig "<<pos<<"'s card "<<i<<" is "<<pig[pos].card[i]<<",vis is "<<pig[pos].vis[i]<<endl;
if(pig[pos].card[i]=='P'&&pig[pos].HP<4&&(!pig[pos].vis[i])){
//cout<<"Pig "<<pos<<" use peach,HP="<<pig[pos].HP+1<<endl;
peach(pos);pig[pos].HP++;
opt=true;break;
}
if(pig[pos].card[i]=='N'&&(!pig[pos].vis[i])){
//cout<<"Pig "<<pos<<" used SouthPig_Invade"<<endl;
opt=true;
pig[pos].vis[i]=true;
int res=invade(pos);
if(res==-1) return;
else break;
}
if(pig[pos].card[i]=='W'&&(!pig[pos].vis[i])){
//cout<<"Pig "<<pos<<" used Arrays_Shoot"<<endl;
opt=true;
pig[pos].vis[i]=true;
int res=arrow(pos);
if(res==-1) return;
else break;
}
if(pig[pos].card[i]=='Z'&&(!pig[pos].vis[i])){
//cout<<"Pig "<<pos<<" equipped crossbow"<<endl;
opt=true;
pig[pos].vis[i]=true;
crossbow(pos);
break;
}
if(pig[pos].card[i]=='F'&&(!pig[pos].vis[i])){
if(pig[pos].opt==2){
opt=true;pig[pos].vis[i]=true;
if(execute_duel(pos,1)) break;
else return;
}else if(pig[pos].opt==1){
bool tmp=false;
for(int j=pig[pos].nxt;j!=pos;j=pig[j].nxt){
if(pig[j].pos==2){
opt=true;pig[pos].vis[i]=true;
if(execute_duel(pos,j)){
tmp=true;break;
}
else return;
}
}
if(tmp) break;
}else{
bool tmp=false;
for(int j=pig[pos].nxt;j!=pos;j=pig[j].nxt){
if(pig[pig[pos].nxt].pos==2||pig[pig[pos].nxt].pos==3){
opt=true;pig[pos].vis[i]=true;
if(execute_duel(pos,j)){
tmp=true;break;
}
else return;
}
}
if(tmp) break;
}
}
if(pig[pos].card[i]=='K'&&(!pig[pos].vis[i])&&((!pig[pos].kill)||pig[pos].equip)){ if(pig[pos].kill&&(!pig[pos].equip)) continue;
if(pig[pos].opt==2){
if(pig[pig[pos].nxt].pos==0||pig[pig[pos].nxt].pos==1){
opt=true;pig[pos].vis[i]=true;
if(execute_kill(pos)) break;
else return;
}
}else if(pig[pos].opt==1){
if(pig[pig[pos].nxt].pos==2){
opt=true;pig[pos].vis[i]=true;
if(execute_kill(pos)) break;
else return;
}
}else if(pig[pig[pos].nxt].pos==2||pig[pig[pos].nxt].pos==3){
opt=true;pig[pos].vis[i]=true;
if(execute_kill(pos)) break;
else return;
}
}
}
while(pig[pos].vis[pig[pos].l]) pig[pos].l++;
while(pig[pig[pos].nxt].dead) pig[pos].nxt=pig[pig[pos].nxt].nxt;
}
while(pig[pos].vis[pig[pos].l]) pig[pos].l++;
pos=pig[pos].nxt;
// for(int i=1;i<=n;i++){
// //cout<<i<<"'s role is "<<pig[i].opt<<",now is "<<pig[i].pos<<",HP is "<<pig[i].HP<<endl;
// for(int j=pig[i].l;j<=pig[i].r;j++){
// if(!pig[i].vis[j]) //cout<<pig[i].card[j]<<" ";
// }
// //cout<<endl;
// }
// //cout<<endl;
}
}
signed main(){
n=read(),m=read();
for(int i=1;i<=n;i++){
char str[WR];
scanf("%s",str+1);
pig[i].HP=4;
pig[i].pos=-1;
pig[i].nxt=i%n+1;
pig[i].l=1;pig[i].r=4;
if(str[1]=='M') pig[i].opt=0;
else if(str[1]=='F') pig[i].opt=2,cntf++;
else pig[i].opt=1;
for(int j=1;j<=4;j++){
scanf("%s",str+1);
pig[i].card[j]=str[1];
}
}
pig[1].pos=0;
for(int i=1;i<=m;i++){
char str[WR];
scanf("%s",str+1);
card[i]=str[1];
}
play();
return 0;
}
用时长达将近3天,果然我是废物/kk
本文来自博客园,作者:冬天丶的雨,转载请注明原文链接:https://www.cnblogs.com/WintersRain/p/16720724.html
为了一切不改变的理想,为了改变不理想的一切