POJ4001 HDU4121 UVA1589 UVALive5829 Xiangqi紫书

一下午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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值