一下午ac了,狂喜
一个我看了才找对思路的题解
开始思路:把棋盘的正在被将的点画上
麻烦:可能重叠将,可能吃子
现在思路:存棋盘,判断将走的四个点,到底能不能至少有一个躲过将军。先看是否对将注意。
具体见下,还有一个输出棋盘的注释,可以看到。
https://blog.csdn.net/sunlanchang/article/details/56682373
一个找到我错的测试数据,tql
是对将的那个发现
https://blog.csdn.net/weixin_30606669/article/details/96243267?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&dist_request_id=&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control
一个笨笨的常见错误:在外面,命名要对到了!
简化技巧:
(简化不仅省时,而且减少复制粘贴,降低出错可能。实在不行,自己重新写,也不要复制粘贴的风险)
使用宏:
使用中等等级的宏,意思是,不要把文本改了,改了数字就好了,否则乱且报错
使用数组确定方向:可以循环了。注意马,将不共用方向为好,修改时改了马的,没想到将的就走错了。
if(vis[i][y0]=='G'){//wa:少了一个y0的0!
win=0;break;//对将
}else if(vis[i][y0]){
break;//不是对子
/* POJ4001 HDU4121 UVA1589 UVALive5829 Xiangqi */
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define L 10
#define W 9
#define br(a,b) if(vis[(a)][(b)]=='R')return false;else if(vis[(a)][(b)])break
#define _forplus(i,a,b) for( int i=(a); i<=(b); i++)
#define _forsub(i,a,b) for( int i=(a); i>=(b); i--)
#define bc(a,b) if(vis[(a)][(b)])\
if(cnt==0)cnt++;\
else if(vis[(a)][(b)]!='C')break;\
else return false
#define bh(a,b,c,d) if((a)<1||(a)>L||(b)<1||(b)>W)continue;\
if(vis[(a)][(b)]!='H')continue;\
if(vis[(c)][(d)])continue;\
return false
char vis[12][12]={0};
int x,y;
char ch;
int f[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int fx[8][4]={{-1,2,-1,1},{1,2,1,1},{2,1,1,1},
{2,-1,1,-1},{1,-2,1,-1},{-1,-2,-1,-1},{-2,-1,-1,-1},{-2,1,-1,1}};
int n,x0,y0;
int win=0;
inline char mychar(){
int ch=getchar();
while(ch<'A'||ch>'Z')ch=getchar();
return ch;
}
bool can(int x,int y){
//判断是否出界
if(x<1||x>3||y<4||y>6){
return false;
}
//判断是否前方第一个是将
//同y,看x
for(int i=x+1;i<=L;i++){
if(vis[i][y]=='G')return false;
else if(vis[i][y])break;
}
//判断是否十字第一个有车
_forplus(i,x+1,L){
br(i,y);
}
_forsub(i,x-1,1){
br(i,y);
}
_forplus(j,y+1,W){
br(x,j);
}
_forsub(j,y-1,1){
br(x,j);
}
//判断是否十字第二个有炮
int cnt;
cnt=0;
_forplus(i,x+1,L){
bc(i,y);
}
cnt=0;
_forsub(i,x-1,1){
bc(i,y);
}
cnt=0;
_forplus(j,y+1,W){
bc(x,j);
}
cnt=0;
_forsub(j,y-1,1){
bc(x,j);
}
//判断是否八方有马,且不越界,不bang脚
_forplus(i,0,7){
bh(x+fx[i][0],y+fx[i][1],x+fx[i][2],y+fx[i][3]);
}
return true;
}
int main()
{
while(~scanf("%d%d%d",&n,&x0,&y0)&&n)
{
//涂点,0可1不可,2落红子
mem(vis,0);
for(int i=1;i<=n;i++){
ch=mychar();
scanf("%d%d",&x,&y);
vis[x][y]=ch;
}
/*//看棋盘
printf("\n ");
for(int i=1;i<=9;i++){
printf("%d",i);
}
putchar('\n');
for(int i=1;i<=10;i++){
printf("%-3d",i);
for(int j=1;j<=9;j++){
if(i==x0&&j==y0){
putchar('J');continue;
}else if(!vis[i][j]){
putchar('-');continue;
}
printf("%c",vis[i][j]);
}
putchar('\n');
}*/
win=1;//红方win为1
_forplus(i,x0+1,L){
if(vis[i][y0]=='G'){//wa:少了一个y0的0!
win=0;break;//对将
}else if(vis[i][y0]){
break;//不是对子
}
}
if(win==0){
printf("NO\n");
}else{
//开始判断四点可否走,有一点可走则NO
for(int i=0;i<4;i++){
if(can(x0+f[i][0],y0+f[i][1])){//true可走,false不可走
win=0;break;
}
}
printf("%s\n",(win?"YES":"NO"));
}
}
return 0;
}