原题链接
题目描述
这题真的很水,只需要用到一个算法——模拟算法
题目的大致意思如下:
有一个游戏,名字叫做鸭棋,这个游戏与象棋十分相似,但是象可以过河,是和将都可以出格,而且没有炮,原来的炮变成了鸭。棋子的走法与原来一样,鸭的话,最多可以到达8个点:
但是,并不是所有情况下这些点都可以去,有一个情况叫做蹩鸭腿:
当你想要从深绿色的点去到浅绿色的点时,必须在当前这条路上的所有红点都没有棋子时才能实现(黑色的斜线和格子中间的线便是路线)。
棋盘的初始形态为:
注意:棋盘的左下角才是坐标 ( 0 , 0 ) (0,0) (0,0)
另外,还有一点温馨提示:棋手下棋的顺序为:红方,蓝方,红方,蓝方……
输入格式
第一行一个非负整数 n ( n ≤ 1000 ) n(n\le 1000) n(n≤1000),表示操作序列的长度。接下来依次描述每个操作。接下来n行,每行4个整数,表示欲将 ( y 1 , x 1 ) (y_1,x_1) (y1,x1)处棋子移动到 ( y 2 , x 2 ) (y_2,x_2) (y2,x2)处的操作。
注意:输入的坐标都为先行再列。
输出格式
输出 QQ 行,对于每个操作依次输出复现结果。每行输出一个操作的结果:
如果该操作为不合法操作,则请输出 Invalid command。
如果为合法操作,则依次回答「题目描述」中的问题 1 ∼ 4 1\sim 4 1∼4:
- 被移动的棋子用 [ [ [颜色 ] ] ] [ [ [类型 ] ] ](注意中间包含空格)来描述,请使用它们的英文名称(见「附注」)。如,红象为 red elephant,蓝王为 blue captain。
- 被移出游戏的棋子的描述方式与上面类似。特别地,如果无棋子被移出游戏,则该问题的答案为 NA。
- 用 yes、no 分别表示形成、不形成将军局面。
- 用 yes、no 分别表示游戏结束、游戏不结束。
用“ ; ”(分号)将所有问题的答案隔开。
比如,四个问题的答案分别为:被移动的棋子是蓝车,无棋子被移出游戏,形成将军局面,游戏未结束。则该行应输出car;NA;yes;no
附注
王(captain)
士(guard)
象(elephant)
马(horse)
车(car)
鸭(duck)
兵(soldier)
解题思路
没什么说的,就是暴力模拟,只是代码有亿点长。
代码实现
#include<bits/stdc++.h>
using namespace std;
int x_2,y_2,x_1,y_1,n,s_way[8][2]={
{
0,1},{
1,0},{
-1,0},{
0,-1},{
1,1},{
1,-1},{
-1,-1},{
-1,1}}/*兵的移动方向*/,king_way[4][2]={
{
0,1},{
1,0},{
-1,0},{
0,-1}}/*将的移动方向*/;
int g_way[4][2]={
{
1,1},{
1,-1},{
-1,1},{
-1,-1}}/*士的移动方向*/,e_way[4][2]={
{
2,2},{
2,-2},{
-2,2},{
-2,-2}};/*象的移动方向*/
int h_way[8][2][2]={
{
{
1,-2},{
0,-1}},{
{
2,-1},{
1,0}},{
{
2,1},{
1,0}},{
{
1,2},{
0,1}},{
{
-1,2},{
0,1}},{
{
-2,1},{
-1,0}},{
{
-2,-1},{
-1,0}},{
{
-1,-2},{
0,-1}}}/*马的移动方向{
{去终点的坐标对于当前位置的变化},{蹩马腿,对于当前位置的坐标变化}}*/;
int d_way[8][2][2][2]=
{
{
{
{
-3,2},{
0,0}},{
{
-1,0},{
-2,1}}},
{
{
{
-2,3},{
0,0}},{
{
0,1},{
-1,2}}},
{
{
{
2,3},{
0,0}},{
{
0,1},{
1,2}}},
{
{
{
3,2},{
0,0}},{
{
1,0},{
2,1}}},
{
{
{
3,-2},{
0,0}},{
{
1,0},{
2,-1}}},
{
{
{
2,-3},{
0,0}},{
{
0,-1},{
1,-2}}},
{
{
{
-2,-3},{
0,0}},{
{
0,-1},{
-1,-2}}},
{
{
{
-3,-2},{
0,0}},{
{
-1,0},{
-2,-1}}}}/*鸭的移动方向{
{去终点的坐标对于当前位置的变化},{蹩鸭腿,对于当前位置的坐标变化}}*/;
int color=1;
string ans_chess[200],ans_color[10];
bool game=true,f1,f2,f3,f4;
char a[10][9]=
{
{
'c','h','e','g','k','g','e','h','c'},
{
' ',' ',' ',' ',' ',' ',' ',' ',' '},
{
'd',' ',' ',' ',' ',' ',' ',' ','d'},
{
's',' ','s',' ','s',' ','s',' ','s'},
{
' ',' ',' ',' ',' ',' ',' ',' ',' '},
{
' ',' ',' ',' ',' ',' ',' ',' ',' '},
{
's',' ','s',' ','s',' ','s',' ','s'},
{
'd',' ',' ',' ',' ',' ',' ',' ','d'},
{
' ',' ',' ',' ',' ',' ',' ',' ',' '},
{
'c','h','e','g','k','g','e','h','c'}
};//初始棋盘
int c[10][9]=
{
{
2,2,2,2,2,2,2,2,2},
{
0,0,0,0,0,0,0,0,0},
{
2,0,0,0,0,0,0,0,2},
{
2,0,2,0,2,0,2,0,2},
{
0,0,0,0,0,0,0,0,0},
{
0,0,0,0,0,0,0,0,0},
{
1,0,1,0,1,0,1,0,1},
{
1,0,0,0,0,0,0,0,1},
{
0,0,0,0,0,0,0,0,0},
{
1,1,1,1,1,1,1,1,1}
};//颜色,1为蓝色,2为红色,倒过来方便处理
bool chk(int x,int y)//出界判断
{
return x>=0&&x<10&&y>=0&&y<9;
}
void setup()//字母对应的棋子和数字对应的颜色
{
ans_chess['k']="captain";
ans_chess['g']="guard";
ans_chess['e']="elephant";
ans_chess['h']="horse";
ans_chess['c']="car";
ans_chess['d']="duck";
ans_chess['s']="soldier";
ans_color[1]="blue";
ans_color[2]="red";
return;
}
bool move_king(int x,int y,int ex,int ey,int cl)//判断王的移动
{
for(int i=0;i<4;i++)
if(chk(x+king_way[i][0],y+king_way[i][1]))//检查是否出界
if(x+king_way[i][0]==ex&&y+king_way[i][1]==ey)//判断是否到达终点
return true;
return false;
}
bool move_soldier(int x,int y,int ex,int ey,int cl)//判断兵的移动
{
for(int i=0;i<8;i++)
if(chk(x+s_way[i][0],y+s_way[i][1]))//检查是否出界
if(x+s_way[i][0]==ex&&y+s_way[i][1]==ey)//判断是否到达终点
return true;
return false;
}
bool move_guard(int x,int y,int ex,int ey,int cl)//判断士的移动
{
for(int i=0;i<4;i++)
if(chk(x+g_way[i][0],y+g_way[i][1]))//检查是否出界
if(x+g_way[i][0]==ex&&y+g_way[i][1]==ey)//判断是否到达终点
return true;
return false;
}
bool move_elephant(int x,int y,int ex,int ey,int cl)//判断象的移动
{
for(int i=0;i<4;i++)
if(chk(x+e_way[i][0],y+e_way[i][1])&&a[x+e_way[i][0]/2][y+e_way[i][1]/2]==' ')//检查是否出界和是否蹩象腿
if(x+e_way[i][0]==ex&&y+e_way[i][1]==ey)//判断是否到达终点
return true;
return false;
}
bool move_horse(int x,int y,int ex,int ey,int cl)//判断马的移动
{
for(int i=0;i<8;i++)
if(chk(x+h_way[i][0][0],y+h_way[i][0][1])&&a[x+h_way[i][1][0]][y+h_way[i][1][1]]==' ')//检查是否出界和是否蹩马腿
if(x+h_way[i][0][0]==ex&&y+h_way[i][0][1]==ey)//判断是否到达终点
return true;
return false;
}
bool move_car(int x,int y,int ex,int ey,int cl)//判断车的移动
{
if(x!=ex&&y!=ey)
return false;
int x_change,y_change;//x和y的变化方向
if(x!=ex)
if(x<ex){
x_change=1;
y_change=0;
}
else{
x_change=-1;
y_change=0;
}
else{
if(y<ey){
x_change=0;
y_change=1;
}
else{
x_change=0;
y_change=-1;
}
}
while(x!=ex||y!=ey){
//判断是否到达终点
x+=x_change;
y+=y_change;
if(!chk(x,y))//检查是否出界
return false;
if(a[x][y]!=' '&&(x!=ex||y!=ey))
return false;
}
return true;
}
bool move_duck(int x,int y,int ex,int ey,int cl)//判断鸭的移动
{
for(int i=0;i<8;i++)
if(chk(x+d_way[i][0][0][0],y+d_way[i][0][0][1])&&a[x+d_way[i][1][0][0]][y+d_way[i][1][0][1]]==' '&&a[x+d_way[i][1][1][0]][y+d_way[i][1][1][1]]==' ')//检查是否出界和是否蹩鸭腿
if(x+d_way[i][0][0][0]==ex&&y+d_way[i][0][0][1]==ey)//判断是否到达终点
return true;
return false;
}
bool c_m()//判断是否将军
{
int k_p[10][10];
for(int i=0;i<10;i++)//获取将军的位置
for(int j=0;j<9;j++)
if(a[i][j]=='k'){
k_p[c[i][j]][0]=i;
k_p[c[i][j]][1]=j;
}
for(int i=0;i<10;i++){
//将棋盘上每一个棋都判断一次是否可以一步吃掉将军
for(int j=0;j<9;j++){
if(c[i][j]==1){
switch(a[i][j]){
case 'k':{
if(move_king(i,j,k_p[2][0],k_p[2][1],1))
return true;
break;
}
case 'c':{
if(move_car(i,j,k_p[2][0],k_p[2][1],1))
return true;
break;
}
case 'e':{
if(move_elephant(i,j,k_p[2][0],k_p[2][1],1))
return true;
break;
}
case 'g':{
if(move_guard(i,j,k_p[2][0],k_p[2][1],1))
return true;
break;
}
case 'h':{
if(move_horse(i,j,k_p[2][0],k_p[2][1],1))
return true;
break;
}
case 's':{
if(move_soldier(i,j,k_p[2][0],k_p[2][1],1))
return true;
break;
}
case 'd':{
if(move_duck(i,j,k_p[2][0],k_p[2][1],1))
return true;
break;
}
}
}
else if(c[i][j]==2){
switch(a[i][j]){
case 'k':{
if(move_king(i,j,k_p[1][0],k_p[1][1],2))
return true;
break;
}
case 'c':{
if(move_car(i,j,k_p[1][0],k_p[1][1],2))
return true;
break;
}
case 'e':{
if(move_elephant(i,j,k_p[1][0],k_p[1][1],2))
return true;
break;
}
case 'g':{
if(move_guard(i,j,k_p[1][0],k_p[1][1],2))
return true;
break;
}
case 'h':{
if(move_horse(i,j,k_p[1][0],k_p[1][1],2))
return true;
break;
}
case 's':{
if(move_soldier(i,j,k_p[1][0],k_p[1][1],2))
return true;
break;
}
case 'd':{
if(move_duck(i,j,k_p[1][0],k_p[1][1],2))
return true;
break;
}
}
}
}
}
return false;
}
void back_step()//移动棋子
{
c[x_2][y_2]=c[x_1][y_1];
c[x_1][y_1]=0;
a[x_2][y_2]=a[x_1][y_1];
a[x_1][y_1]=' ';
return;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie();
cin>>n;
setup();
for(int i=1;i<=n;i++){
cin>>x_1>>y_1>>x_2>>y_2;
if(!chk(x_1,y_1)||!chk(x_2,y_2)){
cout<<"Invalid command"<<endl;
continue;
}
if(!game){
cout<<"Invalid command"<<endl;
continue;
}
if(a[x_1][y_1]==' '||x_1==x_2&&y_1==y_2){
cout<<"Invalid command"<<endl;
continue;
}
if(c[x_2][y_2]==c[x_1][y_1]){
cout<<"Invalid command"<<endl;
continue;
}
if(c[x_1][y_1]!=color+1){
cout<<"Invalid command"<<endl;
continue;
}
f1=false;
switch(a[x_1][y_1]){
case 'k':{
if(move_king(x_1,y_1,x_2,y_2,c[x_1][y_1])){
cout<<ans_color[c[x_1][y_1]]<<" "<<ans_chess[a[x_1][y_1]]<<";";//移动的棋子
if(c[x_2][y_2]!=c[x_1][y_1]&&c[x_2][y_2]!=0){
cout<<ans_color[c[x_2][y_2]]<<" "<<ans_chess[a[x_2][y_2]]<<";";//被吃的棋子
if(a[x_2][y_2]=='k')//游戏结束
game=false;
}
else{
cout<<"NA;";//没有棋被吃
}
back_step();//将棋子移动
f1=true;
}
break;
}
case 's':{
if(move_soldier(x_1,y_1,x_2,y_2,c[x_1][y_1])){
cout<<ans_color[c[x_1][y_1]]<<" "<<ans_chess[a[x_1][y_1]]<<";";//移动的棋子
if(c[x_2][y_2]!=c[x_1][y_1]&&c[x_2][y_2]!=0){
cout<<ans_color[c[x_2][y_2]]<<" "<<ans_chess[a[x_2][y_2]]<<";";//被吃的棋子
if(a[x_2][y_2]=='k')//游戏结束
game=false;
}
else{
cout<<"NA;";//没有棋被吃
}
back_step();//将棋子移动
f1=true;
}
break;
}
case 'g':{
if(move_guard(x_1,y_1,x_2,y_2,c[x_1][y_1])){
cout<<ans_color[c[x_1][y_1]]<<" "<<ans_chess[a[x_1][y_1]]<<";";//移动的棋子
if(c[x_2][y_2]!=c[x_1][y_1]&&c[x_2][y_2]!=0){
cout<<ans_color[c[x_2][y_2]]<<" "<<ans_chess[a[x_2][y_2]]<<";";//被吃的棋子
if(a[x_2][y_2]=='k')//游戏结束
game=false;
}
else{
cout<<"NA;";//没有棋被吃
}
back_step();//将棋子移动
f1=true;
}
break;
}
case 'e':{
if(move_elephant(x_1,y_1,x_2,y_2,c[x_1][y_1])){
cout<<ans_color[c[x_1][y_1]]<<" "<<ans_chess[a[x_1][y_1]]<<";";//移动的棋子
if(c[x_2][y_2]!=c[x_1][y_1]&&c[x_2][y_2]!=0){
cout<<ans_color[c[x_2][y_2]]<<" "<<ans_chess[a[x_2][y_2]]<<";";//被吃的棋子
if(a[x_2][y_2]=='k')//游戏结束
game=false;
}
else{
cout<<"NA;";//没有棋被吃
}
back_step();//将棋子移动
f1=true;
}
break;
}
case 'd':{
if(move_duck(x_1,y_1,x_2,y_2,c[x_1][y_1])){
cout<<ans_color[c[x_1][y_1]]<<" "<<ans_chess[a[x_1][y_1]]<<";";//移动的棋子
if(c[x_2][y_2]!=c[x_1][y_1]&&c[x_2][y_2]!=0){
cout<<ans_color[c[x_2][y_2]]<<" "<<ans_chess[a[x_2][y_2]]<<";";//被吃的棋子
if(a[x_2][y_2]=='k')//游戏结束
game=false;
}
else{
cout<<"NA;";//没有棋被吃
}
back_step();//将棋子移动
f1=true;
}
break;
}
case 'c':{
if(move_car(x_1,y_1,x_2,y_2,c[x_1][y_1])){
cout<<ans_color[c[x_1][y_1]]<<" "<<ans_chess[a[x_1][y_1]]<<";";//移动的棋子
if(c[x_2][y_2]!=c[x_1][y_1]&&c[x_2][y_2]!=0){
cout<<ans_color[c[x_2][y_2]]<<" "<<ans_chess[a[x_2][y_2]]<<";";//被吃的棋子
if(a[x_2][y_2]=='k')//游戏结束
game=false;
}
else{
cout<<"NA;";//没有棋被吃
}
back_step();//将棋子移动
f1=true;
}
break;
}
case 'h':{
if(move_horse(x_1,y_1,x_2,y_2,c[x_1][y_1])){
cout<<ans_color[c[x_1][y_1]]<<" "<<ans_chess[a[x_1][y_1]]<<";";//移动的棋子
if(c[x_2][y_2]!=c[x_1][y_1]&&c[x_2][y_2]!=0){
cout<<ans_color[c[x_2][y_2]]<<" "<<ans_chess[a[x_2][y_2]]<<";";//被吃的棋子
if(a[x_2][y_2]=='k')//游戏结束
game=false;
}
else{
cout<<"NA;";//没有棋被吃
}
back_step();//将棋子移动
f1=true;
}
break;
}
}
if(!f1){
cout<<"Invalid command"<<endl;//走不了
continue;
}
if(c_m())//是否将军
cout<<"yes;";
else
cout<<"no;";
if(game)//游戏是否结束
cout<<"no"<<endl;
else
cout<<"yes"<<endl;
color=(color+1)%2;//当前棋手的编号
}
}
样例
输入
18
0 0 7 0
9 0 8 0
0 1 1 3
0 2 2 0
0 3 1 2
0 4 0 3
9 4 8 4
3 2 2 3
7 0 4 2
7 0 5 3
9 2 7 4
2 0 4 3
9 1 8 3
4 3 6 6
7 4 9 2
8 4 9 4
6 6 9 4
9 8 8 8
输出
Invalid command
Invalid command
Invalid command
Invalid command
red guard;NA;no;no
Invalid command
blue captain;NA;no;no
red soldier;NA;no;no
Invalid command
Invalid command
blue elephant;NA;no;no
red duck;NA;no;no
blue horse;NA;no;no
red duck;blue soldier;no;no
Invalid command
blue captain;NA;yes;no
red duck;blue captain;no;yes
Invalid command