题目大意:考虑一个象棋残局,其中红方有n(2<=n<=7)个棋子,黑方只有一个将。红方除了有一个帅(G)之外还有3种可能的棋子:车(R),马(H),炮(C),并且还需要考虑“别马脚”与将和帅不能照面(将、帅如果同在一条线上,中间又不隔着任何棋子的情况下,走子的一方获胜)的规则。输入所有棋子的位置,保证局面合法并且红方已经将军。你的任务是判断红方是否已经把黑方将死。
解题思路:
- 将和帅是否在同一条线上,若是则红方败,输出NO,否则输出YES
- 判断黑方是否有位置可以走而不被将死,若不存在则表明黑方已被将死,输出YES,否则输出NO
(对不懂象棋规则的人来说削微有点儿坑,我就是被坑了,还有就是输入输出本来我用的scanf和printf,一直wa,改为cin和cout以后就对了(╥╯^╰╥))
AC代码:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
using namespace std;
#define io ios::sync_with_stdio(0),cin.tie(0)
#define ms(arr) memset(arr,0,sizeof(arr))
#define mc(a,b) memcpy(a,b,sizeof(b))
#define inf 0x3f3f3f
#define fin freopen("in.txt", "r", stdin)
#define fout freopen("out.txt", "w", stdout)
typedef long long ll;
typedef unsigned long long ULL;
const int mod=1e9+7;
const int N=1e5+7;
struct node
{
int x,y;
char ch;
} a[110];
int n,x,y;
char arr[15][15];
int dx[]= {0,0,-1,1};
int dy[]= {-1,1,0,0};
int dxx[]= {-1,-2,1,2,-2,-1,1,2};
int dyy[]= {-2,-1,2,1,1,2,-2,-1};
int dxxx[]= {-1,-1,1,1,-1,-1,1,1};
int dyyy[]= {-1,-1,1,1,1,1,-1,-1};
bool judge(int a,int b)
{
int r,c;
r=a;
c=b;
while(r>=1)
{
if(arr[r][c]=='R') return false;
else if(arr[r][c]=='H'||arr[r][c]=='C') break;
r--;
}
r=a;
while(r<=10)
{
if(arr[r][c]=='R'||arr[r][c]=='G') return false;
else if(arr[r][c]=='H'||arr[r][c]=='C') break;
r++;
}
r=a;
while(c>=1)
{
if(arr[r][c]=='R') return false;
else if(arr[r][c]=='H'||arr[r][c]=='C') break;
c--;
}
c=b;
while(c<=10)
{
if(arr[r][c]=='R') return false;
else if(arr[r][c]=='H'||arr[r][c]=='C') break;
c++;
}
c=b;
for(int i=0; i<8; i++)
{
int xx=r+dxx[i];
int yy=c+dyy[i];
int xxx=r+dxxx[i];
int yyy=c+dyyy[i];
if(xx>=1&&x<=10&&yy>=1&&yy<=9)
if(arr[xx][yy]=='H'&&arr[xxx][yyy]=='0') return false;
}
int cnt=0;
while(r>=1)
{
if(arr[r][c]!='0') cnt++;
if(cnt==2&&arr[r][c]=='C') return false;
if(cnt>=2) break;
r--;
}
r=a;
cnt=0;
while(r<=10)
{
if(arr[r][c]!='0') cnt++;
if(cnt==2&&arr[r][c]=='C') return false;
if(cnt>=2) break;
r++;
}
r=a;
cnt=0;
while(c>=1)
{
if(arr[r][c]!='0') cnt++;
if(cnt==2&&arr[r][c]=='C') return false;
if(cnt>=2) break;
c--;
}
c=b;
cnt=0;
while(c<=10)
{
if(arr[r][c]!='0') cnt++;
if(cnt==2&&arr[r][c]=='C') return false;
if(cnt>=2) break;
c++;
}
return true;
}
int main()
{
// fin;
// fout;
while(cin>>n>>x>>y)
{
for(int i=1; i<=10; i++)
for(int j=1; j<=9; j++)
arr[i][j]='0';
if(n==0&&x==0&&y==0) break;
getchar();
for(int i=0; i<n; i++)
{
cin>>a[i].ch>>a[i].x>>a[i].y;
arr[a[i].x][a[i].y]=a[i].ch;
getchar();
}
int i=0;
int r=x,c=y;
int f=0;
while(r<=10)
{
if(arr[r][c]=='G') {f=1; break;}
else if(arr[r][c]!='0') break;
r++;
}
for(i=0; i<4; i++)
{
int xx=x+dx[i];
int yy=y+dy[i];
if(xx>=1&&xx<=3&&yy>=4&&yy<=6)
{
char temp=arr[xx][yy];
arr[xx][yy]='0';
if(judge(xx,yy)) break;
arr[xx][yy]=temp;
}
}
if(i==4&&f==0) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
本文探讨了一道关于象棋残局的算法题,重点在于判断红方是否已将黑方将死。通过分析棋子位置和象棋规则,如“别马脚”和将帅不能照面,设计了一个解决方案,利用C++实现并分享了AC代码。
846

被折叠的 条评论
为什么被折叠?



