P5380 [THUPC2019]鸭棋 题解
本蒟蒻写的第一道大模拟,不喜勿喷。
就是普通的模拟而已,耐心点,一天之内也是能写出来的。
代码只写了两百行左右,比大多数大佬要少。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int M=1e1+7;
int wf[10][9]={
{15,14,13,12,11,12,13,14,15},
{0,0,0,0,0,0,0,0,0},
{16,0,0,0,0,0,0,0,16},
{17,0,17,0,17,0,17,0,17},
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0},
{7,0,7,0,7,0,7,0,7},
{6,0,0,0,0,0,0,0,6},
{0,0,0,0,0,0,0,0,0},
{5,4,3,2,1,2,3,4,5},
};//初始棋盘
bool mapp[10][9],game_overed;
string army[2]={"blue","red"};
string name[8]={"","captain","guard","elephant","horse","car","duck","soldier"};
int q,red,now,rk_x=0,rk_y=4,bk_x=9,bk_y=4;
inline int read()
{
int w=0,r=1;
char c=getchar();
while(!(isdigit(c)||c=='-'))c=getchar();
if(c=='-')r=-1,c=getchar();
while(isdigit(c))w=w*10+c-'0',c=getchar();
return w*r;
}
bool inn(int xx,int yy){return (xx>=0&&xx<=9&&yy>=0&&yy<=8);}
//以下是各种棋子的可走位置判断
int d_k[2][4]={{-1,0,1,0},{0,1,0,-1}};
void mv_k(int fkd,int sx,int sy){
int tx,ty,tkd;
for(int i=0;i<4;i++){
tx=sx+d_k[0][i],ty=sy+d_k[1][i];
tkd=wf[tx][ty]/10;
if(inn(tx,ty)&&(tkd^fkd||wf[tx][ty]==0))mapp[tx][ty]=true;
}
}//王
int d_g[2][4]={{-1,-1,1,1},{-1,1,1,-1}};
void mv_g(int fkd,int sx,int sy){
int tx,ty,tkd;
for(int i=0;i<4;i++){
tx=sx+d_g[0][i],ty=sy+d_g[1][i];
tkd=wf[tx][ty]/10;
if(inn(tx,ty)&&(tkd^fkd||wf[tx][ty]==0))mapp[tx][ty]=true;
}
}//士
int d_e[2][4]={{-1,-1,1,1},{-1,1,1,-1}};
void mv_e(int fkd,int sx,int sy){
int tx,ty,tkd;
for(int i=0;i<4;i++){
tx=sx+d_e[0][i]*2,ty=sy+d_e[1][i]*2;
int wx=sx+d_e[0][i],wy=sy+d_e[1][i];
tkd=wf[tx][ty]/10;
if(inn(tx,ty)&&(tkd^fkd||wf[tx][ty]==0)&&wf[wx][wy]==0)mapp[tx][ty]=true;
}
}//象
int d_h[2][4]={{-1,0,1,0},{0,1,0,-1}};
void mv_h(int fkd,int sx,int sy){
int tx,ty,wx,wy,tkd;
for(int i=0;i<4;i++){
wx=sx+d_h[0][i],wy=sy+d_h[1][i];
if(inn(wx,wy)&&wf[wx][wy]==0)
for(int j=-1;j<=1;j+=2){
if(wx==sx)tx=wx+j,ty=wy+d_h[1][i];
else ty=wy+j,tx=wx+d_h[0][i];
tkd=wf[tx][ty]/10;
if(inn(tx,ty)&&(tkd^fkd||wf[tx][ty]==0))mapp[tx][ty]=true;
}
}
}//马
int d_c[2][4]={{-1,0,1,0},{0,1,0,-1}};
void mv_c(int fkd,int sx,int sy){
int tx,ty,tkd;
for(int i=0;i<4;i++){
tx=sx+d_c[0][i],ty=sy+d_c[1][i];
while(inn(tx,ty)&&wf[tx][ty]==0)
mapp[tx][ty]=true,tx+=d_c[0][i],ty+=d_c[1][i];
tkd=wf[tx][ty]/10;
if(inn(tx,ty)&&tkd^fkd)mapp[tx][ty]=true;
}
}//车
int d_d[2][4]={{-1,0,1,0},{0,1,0,-1}};
void mv_d(int fkd,int sx,int sy){
int tx,ty,wx,wy,xx,xy,tkd;
for(int i=0;i<4;i++){
wx=sx+d_d[0][i],wy=sy+d_d[1][i];
if(inn(wx,wy)&&wf[wx][wy]==0)
for(int j=-1;j<=1;j+=2){
if(wx==sx){
xx=wx+j,xy=wy+d_h[1][i];
tx=xx+j,ty=xy+d_h[1][i];
}
else{
xy=wy+j,xx=wx+d_h[0][i];
ty=xy+j,tx=xx+d_h[0][i];
}
tkd=wf[tx][ty]/10;
if(inn(xx,xy)&&wf[xx][xy]==0)
if(inn(tx,ty)&&(tkd^fkd||wf[tx][ty]==0))mapp[tx][ty]=true;
}
}
}//鸭
int d_s[2][8]={{-1,-1,-1,0,1,1,1,0},{-1,0,1,1,1,0,-1,-1}};
void mv_s(int fkd,int sx,int sy){
int tx,ty,tkd;
for(int i=0;i<8;i++){
tx=sx+d_s[0][i],ty=sy+d_s[1][i];
tkd=wf[tx][ty]/10;
if(inn(tx,ty)&&(tkd^fkd||wf[tx][ty]==0))mapp[tx][ty]=true;
}
}//兵
bool cck(int sx,int sy,int tx,int ty){
int sd=wf[sx][sy]/10;
if(!sd^now)return false;
if(game_overed)return false;
int kd=wf[sx][sy]%10;
memset(mapp,0,sizeof(mapp));
if(kd==1)mv_k(sd,sx,sy);
if(kd==2)mv_g(sd,sx,sy);
if(kd==3)mv_e(sd,sx,sy);
if(kd==4)mv_h(sd,sx,sy);
if(kd==5)mv_c(sd,sx,sy);
if(kd==6)mv_d(sd,sx,sy);
if(kd==7)mv_s(sd,sx,sy);
return mapp[tx][ty];
}//判断当前操作是否合法
bool acck(){
memset(mapp,0,sizeof(mapp));
for(int i=0;i<=9;i++){
for(int j=0;j<=8;j++){
int sd=wf[i][j]/10,kd=wf[i][j]%10;
if(sd){
if(kd==1)mv_k(sd,i,j);
if(kd==2)mv_g(sd,i,j);
if(kd==3)mv_e(sd,i,j);
if(kd==4)mv_h(sd,i,j);
if(kd==5)mv_c(sd,i,j);
if(kd==6)mv_d(sd,i,j);
if(kd==7)mv_s(sd,i,j);
}
}
}
if(mapp[bk_x][bk_y])return true;
memset(mapp,0,sizeof(mapp));
for(int i=0;i<=9;i++){
for(int j=0;j<=8;j++){
int sd=wf[i][j]/10,kd=wf[i][j]%10;
if(!sd){
if(kd==1)mv_k(sd,i,j);
if(kd==2)mv_g(sd,i,j);
if(kd==3)mv_e(sd,i,j);
if(kd==4)mv_h(sd,i,j);
if(kd==5)mv_c(sd,i,j);
if(kd==6)mv_d(sd,i,j);
if(kd==7)mv_s(sd,i,j);
}
}
}
return mapp[rk_x][rk_y];
}//检查有无将军情况
int main(){
q=read();
for(int i=1,sx,sy,tx,ty;i<=q;i++){
sx=read(),sy=read(),tx=read(),ty=read();
int fr=wf[sx][sy],tr=wf[tx][ty];
if(cck(sx,sy,tx,ty)){
now^=1;
//printf("%d\n",now);
cout<<army[fr/10]<<" "<<name[fr%10]<<";";
if(!tr)printf("NA;");
else cout<<army[tr/10]<<" "<<name[tr%10]<<";";
wf[sx][sy]=0,wf[tx][ty]=fr;
if(fr%10==1){
if(now)rk_x=tx,rk_y=ty;
else bk_x=tx,bk_y=ty;
}
printf(acck()?"yes;":"no;");
if((wf[rk_x][rk_y]!=11||wf[bk_x][bk_y]!=1)&&!game_overed)game_overed=true;
printf(game_overed?"yes\n":"no\n");
}
else printf("Invalid command\n");
}
return 0;
}