就是一道大模拟。

首先,来解释一下复杂的题意:

给你一些棋子,每个棋都有不同的走法,开局是回归原位。

接下来,题目会给你一个虚拟的走子操作(注意不一定真实),你所需要判断当前操作是否正确。若不正确,输出\(Invalid command\)。否则,输出当前操作的棋子其淘汰掉的棋子是否将军对局是否结束这四个信息。

\(OK,\)那我们一步一步来。

走子规则应该不用多讲了吧,我们可以用数组来存储。只是,鸭的走法可能有一部分人看不懂,其实就是马的进化版呀!假设我们说马走日走的是一个\(1 \times 2\),那么鸭子其实就是走的\(2 \times 3\),其本质是一样的。只是,每个棋子都不能超出棋盘,而且其中的马,象,和鸭还要考虑憋腿的情况。

当然还要特别注意的是车的走法,车可以横冲直撞,所以我们不必用数组存,到时候直接向四面八方走即可。

好,走子规则没什么问题,我们来看每一次的操作。

一开始的棋盘是初始化的,我们用\(a[i][j]\)表示第\(i\)行\(j\)列的棋子\((1\)~\(7)\),用\(h[i][j]\)表示的第\(i\)行\(j\)列的棋子的颜色。(红表示\(1\),蓝表示\(2\))。

然后来看,对于每个操作,我们把棋子的出发点做起点,棋子的到达点叫做落点。那么,如果起点和落点有任何一个不存在,也就是超出棋盘范围,说明操作一定是不合法的,所以\(pass\)掉。

接着,我们再用一个\(color\)变量维护当前应该是哪一方走棋。显而易见的,起点一定是本方的,而落点不能是本方的。如果不满足也说明当前操作不合法。

好了,下面我们可以来暴力大模拟了。

大致可以分成几类:

\(step1:\)判断当前是哪枚棋子。不同的棋子,它的走法也不同,所以我们要分类讨论。

\(step2:\)对于当前棋子,我们遍历它的所有走法。寻找是否有落点与题目中给出的落点吻合。如果吻合,判断当前落点是否有棋子,如果没有,就判断它是什么棋子。然后再对当前点进行移动。最后别忘记,如果一遍扫下来都没有和给出的落点相吻合,那么输出\(Invalid command\)。

\(step3:\)看当前局面是否存在将军。我们可以分别判断,无疑也就两种情况:

  • 是否有红棋可以淘汰蓝将

  • 是否有蓝棋可以淘汰红将

如果满足其一,说明存在将军局面,输出\(yes\),否则输出\(no\)。

\(step4:\)看当前局面中是否还存在两个王,如果只剩一个,说明另外一个已经被淘汰了,也就是游戏已经结束。

【特别注意】

  • 如果当前操作不合法,那么本来哪方走棋,接下来还是哪方走棋,不用变化。

  • 如果游戏已经结束,后面的操作就不用执行了,直接输出\(Invalid command\)即可。

\(Code:\)

#include<bits/stdc++.h>
using namespace std;
inline int read(){
register int s=0,f=1;
register char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f*=-1;ch=getchar();}
while(isdigit(ch))s=(s<<1)+(s<<3)+(ch^48),ch=getchar();
return s*f;
}
const int captain[20][5]={
{0,1},{1,0},{0,-1},{-1,0}
};
const int guard[20][5]={
{1,1},{1,-1},{-1,1},{-1,-1}
};
const int elephant[20][5]={
{2,-2},{-2,2},{2,2},{-2,-2}
};
const int Elephant[20][5]={
{1,-1},{-1,1},{1,1},{-1,-1}
};
const int horse[20][5]={
{2,-1},{2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2},{1,-2}
};
const int Horse[20][5]={
{1,0},{1,0},{0,1},{0,1},{-1,0},{-1,0},{0,-1},{0,-1}
};
const int duck[20][5]={
{3,2},{-3,2},{2,3},{2,-3},{3,-2},{-3,-2},{-2,3},{-2,-3}
};
const int Duck[20][5]={
{1,0},{-1,0},{0,1},{0,-1},{1,0},{-1,0},{0,1},{0,-1},
{2,1},{-2,1},{1,2},{1,-2},{2,-1},{-2,-1},{-1,2},{-1,-2}
};
const int soldier[20][5]={
{0,1},{1,0},{0,-1},{-1,0},{1,1},{-1,-1},{1,-1},{-1,1}
};
//每个子的走法如上
int color,End,flg;
int a[20][20],h[20][20];
string f[10];
void Clean(){
f[1]="captain";f[2]="guard";
f[3]="elephant";f[4]="horse";
f[5]="car";f[6]="duck";f[7]="soldier";//数字对应棋子 a[1][1]=a[1][9]=5,h[1][1]=h[1][9]=1;
a[1][2]=a[1][8]=4,h[1][2]=h[1][8]=1;
a[1][3]=a[1][7]=3,h[1][3]=h[1][7]=1;
a[1][4]=a[1][6]=2,h[1][4]=h[1][6]=1;
a[1][5]=1,h[1][5]=1;
a[3][1]=a[3][9]=6,h[3][1]=h[3][9]=1;
a[4][1]=a[4][3]=a[4][5]=a[4][7]=a[4][9]=7;
h[4][1]=h[4][3]=h[4][5]=h[4][7]=h[4][9]=1; a[10][1]=a[10][9]=5,h[10][1]=h[10][9]=2;
a[10][2]=a[10][8]=4,h[10][2]=h[10][8]=2;
a[10][3]=a[10][7]=3,h[10][3]=h[10][7]=2;
a[10][4]=a[10][6]=2,h[10][4]=h[10][6]=2;
a[10][5]=1,h[10][5]=2;
a[8][1]=a[8][9]=6,h[8][1]=h[8][9]=2;
a[7][1]=a[7][3]=a[7][5]=a[7][7]=a[7][9]=7;
h[7][1]=h[7][3]=h[7][5]=h[7][7]=h[7][9]=2; //初始化棋盘
}
bool bianjie(int x,int y){//边界判断
if(x>=1&&x<=10&&y>=1&&y<=9)return true;
return false;
}
void Jiangjun(int x){//将军判断,x表示将哪一方的军
for(int i=1;i<=10;i++){
for(int j=1;j<=9;j++){
if(h[i][j]==x)continue;//当前点必须是对方的
if(a[i][j]==1){//开始模拟每一个棋子
for(int k=0;k<4;k++){
int tx=i+captain[k][0];
int ty=j+captain[k][1];
if(h[tx][ty]==x&&a[tx][ty]==1){
flg=1;
return;
}
}
}else if(a[i][j]==2){
for(int k=0;k<4;k++){
int tx=i+guard[k][0];
int ty=j+guard[k][1];
if(h[tx][ty]==x&&a[tx][ty]==1){
flg=1;
return;
}
}
}else if(a[i][j]==3){
for(int k=0;k<4;k++){
int tx=i+elephant[k][0];
int ty=j+elephant[k][1];
int px=i+Elephant[k][0];
int py=j+Elephant[k][1];
if(h[px][py])continue;
if(h[tx][ty]==x&&a[tx][ty]==1){
flg=1;
return;
}
}
}else if(a[i][j]==4){
for(int k=0;k<8;k++){
int tx=i+horse[k][0];
int ty=j+horse[k][1];
int px=i+Horse[k][0];
int py=j+Horse[k][1];
if(h[px][py])continue;
if(h[tx][ty]==x&&a[tx][ty]==1){
flg=1;
return;
}
}
}else if(a[i][j]==5){
for(int k=i+1;k<=10;k++){
if(h[k][j]==x&&a[k][j]==1){
flg=1;
return;
}
if(h[k][j])break;
}
for(int k=i-1;k>=1;k--){
if(h[k][j]==x&&a[k][j]==1){
flg=1;
return;
}
if(h[k][j])break;
}
for(int k=j+1;k<=9;k++){
if(h[i][k]==x&&a[i][k]==1){
flg=1;
return;
}
if(h[i][k])break;
}
for(int k=j-1;k>=1;k--){
if(h[i][k]==x&&a[i][k]==1){
flg=1;
return;
}
if(h[i][k])break;
}
}else if(a[i][j]==6){
for(int k=0;k<8;k++){
int tx=i+duck[k][0];
int ty=j+duck[k][1];
int px1=i+Duck[k][0],px2=i+Duck[k+8][0];
int py1=j+Duck[k][1],py2=j+Duck[k+8][1];
if(h[px1][py1]||h[px2][py2])continue;
if(h[tx][ty]==x&&a[tx][ty]==1){
flg=1;
return;
}
}
}else if(a[i][j]==7){
for(int k=0;k<8;k++){
int tx=i+soldier[k][0];
int ty=j+soldier[k][1];
if(h[tx][ty]==x&&a[tx][ty]==1){
flg=1;
return;
}
}
}
}
}
}
void jiangjun(){
Jiangjun(1),Jiangjun(2);//红方是否被将军?蓝方是否被将军?
if(flg==1)cout<<"yes;";
else cout<<"no;";
flg=0;//注意清0哦~
}
bool checkcaptain(){
int tot=0;
for(int i=1;i<=10;i++){
for(int j=1;j<=9;j++){
if(a[i][j]==1)tot++;
}
}
return tot==2;
}
void printst(int x,int y){
if(h[x][y]==1)cout<<"red ";
else cout<<"blue ";
cout<<f[a[x][y]]<<";";
}
void check1(int x,int y,int dx,int dy){
for(int i=0;i<4;i++){
int tx=x+captain[i][0];
int ty=y+captain[i][1];//下一个点
if(tx==dx&&ty==dy){
printst(x,y);//输出当前点
if(h[tx][ty]==2-color%2)printst(tx,ty);//输出下一个点
else cout<<"NA;";
a[tx][ty]=a[x][y],h[tx][ty]=h[x][y];
a[x][y]=h[x][y]=0; jiangjun();//判断是否存在将军局面
if(checkcaptain())cout<<"no"<<"\n";//结束了吗?两个王还在吗?
else cout<<"yes"<<"\n",End=1;
color++;//注意换成对方走棋
return;
}
}
cout<<"Invalid command"<<"\n";
}
void check2(int x,int y,int dx,int dy){
for(int i=0;i<4;i++){
int tx=x+guard[i][0];
int ty=y+guard[i][1];
if(tx==dx&&ty==dy){
printst(x,y);
if(h[tx][ty]==2-color%2)printst(tx,ty);
else cout<<"NA;";
a[tx][ty]=a[x][y],h[tx][ty]=h[x][y];
a[x][y]=h[x][y]=0; jiangjun();
if(checkcaptain())cout<<"no"<<"\n";
else cout<<"yes"<<"\n",End=1;
color++;
return;
}
}
cout<<"Invalid command"<<"\n";
}
void check3(int x,int y,int dx,int dy){
for(int i=0;i<4;i++){
int tx=x+elephant[i][0];
int ty=y+elephant[i][1];
int px=x+Elephant[i][0];
int py=y+Elephant[i][1];
if(h[px][py])continue;
if(tx==dx&&ty==dy){
printst(x,y);
if(h[tx][ty]==2-color%2)printst(tx,ty);
else cout<<"NA;";
a[tx][ty]=a[x][y],h[tx][ty]=h[x][y];
a[x][y]=h[x][y]=0; jiangjun();
if(checkcaptain())cout<<"no"<<"\n";
else cout<<"yes"<<"\n",End=1;
color++;
return;
}
}
cout<<"Invalid command"<<"\n";
}
void check4(int x,int y,int dx,int dy){
for(int i=0;i<8;i++){
int tx=x+horse[i][0];
int ty=y+horse[i][1];
int px=x+Horse[i][0];
int py=y+Horse[i][1];
if(h[px][py])continue;
if(tx==dx&&ty==dy){
printst(x,y);
if(h[tx][ty]==2-color%2)printst(tx,ty);
else cout<<"NA;";
a[tx][ty]=a[x][y],h[tx][ty]=h[x][y];
a[x][y]=h[x][y]=0; jiangjun();
if(checkcaptain())cout<<"no"<<"\n";
else cout<<"yes"<<"\n",End=1;
color++;
return;
}
}
cout<<"Invalid command"<<"\n";
}
void check5(int x,int y,int dx,int dy){
for(int i=x+1;i<=10;i++){//车向四个方向拓展,注意可不能挡它QAQ
int tx=i,ty=y;
if(tx==dx&&ty==dy){
printst(x,y);
if(h[tx][ty]==2-color%2)printst(tx,ty);
else cout<<"NA;";
a[tx][ty]=a[x][y],h[tx][ty]=h[x][y];
a[x][y]=h[x][y]=0; jiangjun();
if(checkcaptain())cout<<"no"<<"\n";
else cout<<"yes"<<"\n",End=1;
color++;
return;
}
if(h[tx][ty])break;
}
for(int i=x-1;i>=1;i--){
int tx=i,ty=y;
if(tx==dx&&ty==dy){
printst(x,y);
if(h[tx][ty]==2-color%2)printst(tx,ty);
else cout<<"NA;";
a[tx][ty]=a[x][y],h[tx][ty]=h[x][y];
a[x][y]=h[x][y]=0; jiangjun();
if(checkcaptain())cout<<"no"<<"\n";
else cout<<"yes"<<"\n",End=1;
color++;
return;
}
if(h[tx][ty])break;
}
for(int i=y+1;y<=9;i++){
int tx=x,ty=i;
if(tx==dx&&ty==dy){
printst(x,y);
if(h[tx][ty]==2-color%2)printst(tx,ty);
else cout<<"NA;";
a[tx][ty]=a[x][y],h[tx][ty]=h[x][y];
a[x][y]=h[x][y]=0; jiangjun();
if(checkcaptain())cout<<"no"<<"\n";
else cout<<"yes"<<"\n",End=1;
color++;
return;
}
if(h[tx][ty])break;
}
for(int i=y-1;y>=1;i--){
int tx=x,ty=i;
if(tx==dx&&ty==dy){
printst(x,y);
if(h[tx][ty]==2-color%2)printst(tx,ty);
else cout<<"NA;";
a[tx][ty]=a[x][y],h[tx][ty]=h[x][y];
a[x][y]=h[x][y]=0; jiangjun();
if(checkcaptain())cout<<"no"<<"\n";
else cout<<"yes"<<"\n",End=1;
color++;
return;
}
if(h[tx][ty])break;
}
cout<<"Invalid command"<<"\n";
}
void check6(int x,int y,int dx,int dy){
for(int i=0;i<8;i++){
int tx=x+duck[i][0];
int ty=y+duck[i][1];
int px1=x+Duck[i][0],px2=x+Duck[i+8][0];
int py1=y+Duck[i][1],py2=y+Duck[i+8][1];
if(h[px1][py1]||h[px2][py2])continue;
if(tx==dx&&ty==dy){
printst(x,y);
if(h[tx][ty]==2-color%2)printst(tx,ty);
else cout<<"NA;";
a[tx][ty]=a[x][y],h[tx][ty]=h[x][y];
a[x][y]=h[x][y]=0; jiangjun();
if(checkcaptain())cout<<"no"<<"\n";
else cout<<"yes"<<"\n",End=1;
color++;
return;
}
}
cout<<"Invalid command"<<"\n";
}
void check7(int x,int y,int dx,int dy){
for(int i=0;i<8;i++){
int tx=x+soldier[i][0];
int ty=y+soldier[i][1];
if(tx==dx&&ty==dy){
printst(x,y);
if(h[tx][ty]==2-color%2)printst(tx,ty);
else cout<<"NA;";
a[tx][ty]=a[x][y],h[tx][ty]=h[x][y];
a[x][y]=h[x][y]=0; jiangjun();
if(checkcaptain())cout<<"no"<<"\n";
else cout<<"yes"<<"\n",End=1;
color++;
return;
}
}
cout<<"Invalid command"<<"\n";
}
int main(){
Clean();
int T=read();
while(T--){
int xs=read()+1,ys=read()+1,xt=read()+1,yt=read()+1;
if((!bianjie(xs,ys))||(!bianjie(xt,yt))||End){//判断程序结束或是起点和落点出了边界
cout<<"Invalid command"<<"\n";
continue;
} if(color%2==0){//判断当前哪一方走棋
if(h[xs][ys]!=1||h[xt][yt]==1){
cout<<"Invalid command"<<"\n";
continue;
}
}else{
if(h[xs][ys]!=2||h[xt][yt]==2){
cout<<"Invalid command"<<"\n";
continue;
}
}
if(a[xs][ys]==1)check1(xs,ys,xt,yt);
else if(a[xs][ys]==2)check2(xs,ys,xt,yt);
else if(a[xs][ys]==3)check3(xs,ys,xt,yt);
else if(a[xs][ys]==4)check4(xs,ys,xt,yt);
else if(a[xs][ys]==5)check5(xs,ys,xt,yt);
else if(a[xs][ys]==6)check6(xs,ys,xt,yt);
else if(a[xs][ys]==7)check7(xs,ys,xt,yt);//分类讨论每一个点
}
return 0;
}

\(\operatorname{Update}\) \(\operatorname{on}\) \(\operatorname{2019.08.03}\)

题解 洛谷P5380 【[THUPC2019]鸭棋】的更多相关文章

  1. 【洛谷】P1541 乌龟棋(四维背包dp)

    题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点,游戏要求玩家控制一个乌龟棋子从起 ...

  2. 【题解】洛谷P1541 [NOIP2010TG] 乌龟棋(类似背包的DP)

    题目来源:洛谷P1541 思路 类似背包的题 总之就是四种卡牌取的先后顺序不同导致的最终ans不同 所以我们用一个四维数组每一维分别表示第几种取了几张的最大分数 然后就是简单DP解决 代码 #incl ...

  3. 题解 洛谷P5018【对称二叉树】(noip2018T4)

    \(noip2018\) \(T4\)题解 其实呢,我是觉得这题比\(T3\)水到不知道哪里去了 毕竟我比较菜,不大会\(dp\) 好了开始讲正事 这题其实考察的其实就是选手对D(大)F(法)S(师) ...

  4. 题解 洛谷 P3396 【哈希冲突】(根号分治)

    根号分治 前言 本题是一道讲解根号分治思想的论文题(然鹅我并没有找到论文),正 如论文中所说,根号算法--不仅是分块,根号分治利用的思想和分块像 似却又不同,某一篇洛谷日报中说过,分块算法实质上是一种 ...

  5. 题解-洛谷P5410 【模板】扩展 KMP(Z 函数)

    题面 洛谷P5410 [模板]扩展 KMP(Z 函数) 给定两个字符串 \(a,b\),要求出两个数组:\(b\) 的 \(z\) 函数数组 \(z\).\(b\) 与 \(a\) 的每一个后缀的 L ...

  6. 题解-洛谷P4229 某位歌姬的故事

    题面 洛谷P4229 某位歌姬的故事 \(T\) 组测试数据.有 \(n\) 个音节,每个音节 \(h_i\in[1,A]\),还有 \(m\) 个限制 \((l_i,r_i,g_i)\) 表示 \( ...

  7. 题解-洛谷P4724 【模板】三维凸包

    洛谷P4724 [模板]三维凸包 给出空间中 \(n\) 个点 \(p_i\),求凸包表面积. 数据范围:\(1\le n\le 2000\). 这篇题解因为是世界上最逊的人写的,所以也会有求凸包体积 ...

  8. 题解-洛谷P4859 已经没有什么好害怕的了

    洛谷P4859 已经没有什么好害怕的了 给定 \(n\) 和 \(k\),\(n\) 个糖果能量 \(a_i\) 和 \(n\) 个药片能量 \(b_i\),每个 \(a_i\) 和 \(b_i\) ...

  9. 题解-洛谷P5217 贫穷

    洛谷P5217 贫穷 给定长度为 \(n\) 的初始文本 \(s\),有 \(m\) 个如下操作: \(\texttt{I x c}\),在第 \(x\) 个字母后面插入一个 \(c\). \(\te ...

随机推荐

  1. LeetCode 238. 除自身以外数组的乘积(Product of Array Except Self)

    238. 除自身以外数组的乘积 238. Product of Array Except Self 题目描述 LeetCode LeetCode238. Product of Array Except ...

  2. TCP/IP协议的工作流程

    1.在源主机上,应用层将一串应用数据流向下传输给传输层 2.传输层将应用数据截流成分组,并加上TCP报头形成TCP段,向下递交给网络层 3.在网络层给TCP段加上包括源主机,目的主机IP地址的IP报头 ...

  3. 06 Mybatis 使用xml配置映射模式+动态SQL---使用案例

    1.项目结构 2.数据库表User对应的实体类 package domain; import java.io.Serializable; import java.util.Date; /** * 数据 ...

  4. 【转帖】MySQL用得好好的,为什么要转ES?

    MySQL用得好好的,为什么要转ES? http://developer.51cto.com/art/201911/605288.htm Elasticsearch作为一款功能强大的分布式搜索引擎,支 ...

  5. 《TCP/IP - TCP/UDP》

    一:概述 - 由于 IP 的传输是无状态的,IP 提供尽力服务,但并不保证数据可以到达主机. - 所以,数据的完整性需要更上层的 传输层来保证.TCP和UDP 均属于 传输层. 二:UDP - 特点 ...

  6. java email发送(附件中文的处理)

    这里使用的是commons-email-1.3.2.jar进行的开发,自认为这是简单的邮件发送. package com.yt.base.common; import java.io.Unsuppor ...

  7. Django框架深入了解_03(DRF之认证组件、权限组件、频率组件、token)

    一.认证组件 使用方法: ①写一个认证类,新建文件:my_examine.py # 导入需要继承的基类BaseAuthentication from rest_framework.authentica ...

  8. python基础 — random库

    python中用于生成伪随机数的函数库是random 因为是标准库,使用时候只需要import random random库包含两类函数,常用的共8个 --基本随机函数: seed(), random ...

  9. Python知识点图片

  10. scrapy爬取相似页面及回调爬取问题(以慕课网为例)

    以爬取慕课网数据为例   慕课网的数据很简单,就是通过get方式获取的 连接地址为https://www.imooc.com/course/list?page=2 根据page参数来分页