习题4-1 uva1589 象棋

题目大意是黑方已经被将军,红方有2到7个棋子,现在轮到黑方行动,判断是否是死局.

拿到的思路:
1.存储红方棋子及其位置
用结构体储存 棋子类型 位置 是否存活(模拟被吃情况)
2.判断是否每个方向都不能走 OK表示是否为死局
想了两种方法;
a.现将红方各个子可以移动到的位置标记(用一个二维数组表示棋盘)
找出黑子所有的移动位置到数组中比对.
这样的问题在于黑子移动是有可能吃掉红子的,感觉不好操作,放弃.
b.先找出黑子的移动,用judge函数判断能否行动
judge函数:
①先判断是否有子被吃,修改survive的值
②遍历红子数组 根据棋子类型代入不同的判断函数
车:不同行列或 同行/列但是中间有子且该子存活
将:不同列或同列但是中间有子且该子存活
炮:不同行列或 同行/列但是中间没有或者有多个存活的子
马:遍历数组判断别马腿
都不能则OK=0;
3.OK=1输出YES否则输出NO
随机数据rand()

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<ctime>
using namespace std;


int main()
{
freopen("D:\\rand.txt", "w", stdout);
srand(unsigned(time(0)));
int maxn = 6, count = 0;
int dir[11][10];
const char s0[] = "RRCCHH";
for (int s = (1<<maxn) - 1; s >= 1; s--)
for (int num = 1000; num; num--)
{
memset(dir, 0, sizeof(dir));
int n = 0, is = 0;
int r0 = 1 + rand() % 3, c0 = 4 + rand() % 3;
dir[r0][c0] = 1;
int r1 = 8 + rand() % 3, c1 = 4 + rand() % 3;
while (c0 == c1)
c1 = 4 + rand() % 3;
dir[r1][c1] = 1;
for (int i = 0; i < maxn; i++)
if (s & (1<<i))
n++;
printf("\n%d %d %d\nG %d %d\n",  n + 1, r0, c0, r1, c1);
for (int i = 0; i < maxn; i++)
if (s & (1<<i))
{
int r = 1 + rand() % 10, c = 1 + rand() % 9;
if (is == 0 && s0[i] != 'C')
{
if (s0[i] != 'H')
{
r = r0 + 1;
c = c0;
}
else
{
r = r0 + 2;
c = c0 + 1;
}
is = 1;
}
else
{
while (dir[r][c])
{
r = 1 + rand() % 10;
c = 1 + rand() % 9;
}
}
dir[r][c] = 1;
printf("%c %d %d\n", s0[i], r, c);
}
}
printf("\n0 0 0");
return 0;
}

ac:

#include<algorithm>
#include<cstdio>
#include<cstring>
int n,r,c;//红棋子个数 黑将行 列
struct node{
		int type;//1 car 2 horse 3 canon 4 boss
		int row;
		int col;
		int survive;
		node():type(0),row(0),col(0),survive(0){};
	};
struct node red[7];//ok=1 can go ok=0 no go
bool car(int row, int col,int j){
	if(red[j].row!=row&&red[j].col!=col) return 1;
	if(red[j].row==row){
		for(int i=0;i<n;i++)
			if(red[i].survive&&red[i].row==row&&(red[i].col-col)*(red[i].col-red[j].col)<0) 
				return 1;
	}
	else if(red[j].col==col)
		{for(int i=0;i<n;i++)
		if(red[i].survive&&red[i].col==col&&(red[i].row-row)*(red[i].row-red[j].row)<0) 
			return 1;
	}
	//printf("wrong");
	 return 0;
}
int compare(int a,int b,int c)//c=0 max c=1 min
{
	if(a>b&&c==0) return a;
	if(a>b&&c==1) return b;
	if(a<=b&&c==0) return b;
	if(a<=b&&c==1) return a;
}
bool horse(int row, int col,int j){
	if(compare(row,red[j].row,0)-compare(row,red[j].row,1)+compare(col,red[j].col,0)-compare(col,red[j].col,1)==3){
		if(row-red[j].row==0||col-red[j].col==0) return 1;
		int dir[5]={0,0,0,0,0};//1 up 2 down 3 right 4left
		for(int i=0;i<n;i++)
			if(red[i].row==red[j].row&&red[i].survive){
				if(red[j].col-red[i].col==1) dir[4]=1;
				else if(red[j].col-red[i].col==-1) dir[3]=1;}
			else if(red[i].col==red[j].col&&red[i].survive){
				if(red[i].row-red[j].row==1) dir[2]=1;
				else if(red[i].row-red[j].row==-1) dir[1]=1;}
			if(red[j].row-row==2&&dir[1]==1) return 1;
			else if(row-red[j].row==2&&dir[2]==1) return 1;
			else if(red[j].col-col==2&&dir[4]==1) return 1;
			else if(col-red[j].col==2&&dir[3]==1) return 1;
			else return 0;
		}
		 return 1;
	}
bool canon(int row, int col,int j){
	int cntr=0,cntc=0;
	if(red[j].row==row)
		for(int i=0;i<n;i++)
			if(red[i].row==row&&red[i].survive&&(red[i].col-col)*(red[i].col-red[j].col)<0) cntr++;
	if(cntr==1) return 0;
	if(red[j].col==col)
		for(int i=0;i<n;i++)
			if(red[i].col==col&&red[i].survive&&(red[i].row-row)*(red[i].row-red[j].row)<0) cntc++;
	if(cntc==1) return 0;
	return 1;}
bool boss(int row, int col,int j){
	int OK=0;
	if(red[j].col==col)
		for(int i=0;i<n;i++)
			if(red[i].col==col&&red[i].survive&&(red[i].row-row)*(red[i].row-red[j].row)<0) OK= 1;
	if(red[j].col!=col) OK=1;
	if(OK)
	return 1;
	else return 0;
}
bool judge(int row,int col)
{
	for(int i=0;i<n;i++)
		if(row==red[i].row&&col==red[i].col) red[i].survive=0;
	int OK=1;
	for(int i=0;i<n;i++){
		if(red[i].survive){
		if(red[i].type==1&&car(row,col,i)==0)  OK= 0;//0 die  1 survive
		if(red[i].type==2&&!horse(row,col,i))  OK= 0;
		if(red[i].type==3&&!canon(row,col,i))  OK= 0;
		if(red[i].type==4&&!boss(row,col,i))   OK= 0;

		//printf("%d\n",OK);

		}}
		for(int i=0;i<n;i++)
		if( red[i].survive==0)red[i].survive=1;
	if(OK)
	 return 1;
	else return 0;

}
int main(){

	
	freopen("D:\\rand.txt","r",stdin);
	freopen("D:\\out.txt","w",stdout);
	while(scanf("%d %d %d",&n,&r,&c)==3&&n){

		//printf("n=%d r=%d c=%d\n" ,n,r,c);


		char b;
		for(int i=0;i<n;i++){
			scanf("\n%c",&b);

			//printf("b=%c\n",b);

			int r1,c1;
			scanf("%d %d\n",&r1,&c1);
			red[i].row=r1;
			red[i].col=c1;
			red[i].survive=1;
			if(b=='R') red[i].type=1;
			else if(b=='H') red[i].type=2;
			else if(b=='C') red[i].type=3;
			else if(b=='G') red[i].type=4;
		
			
		}



		//for(int i=0;i<n;i++)
		//printf("type=%d row=%d col=%d survive=%d\n",red[i].type,red[i].row,red[i].col,red[i].survive);
		//judge black
	/*	printf("1,6,0=%d\n",car(1,6,1));
		printf("1,6=%d\n",judge(1,6));
		printf("2,6,0=%d\n",car(3,6,2));
		printf("2,6=%d\n",judge(3,6));
		printf("2,5=%d\n",judge(2,5));*/
		//printf("2,4=%d\n",judge(2,4));
		
		
		int OK=0;

		for(int i=-1;i<2;i+=2)
			if(r+i>0&&r+i<4) if(judge(r+i,c)) OK=1;
		for(int i=-1;i<2;i+=2)
			if(c+i>3&&c+i<7) if(judge(r,c+i)) OK=1;
		for(int i=0;i<n;i++)
			if(red[i].type==4&&boss(r,c,i)==0) OK=1;
		if(OK) printf("NO");
		else printf("YES");
		printf("\n");
	
	}
	return 0;
}
posted @ 2019-02-01 22:23  少年留不住  阅读(81)  评论(0编辑  收藏  举报