hdu 1691

本文分享了一道关于中国象棋模拟的编程题的解决过程,通过一天多的努力,最终找到了所有可能的错误并实现了正确的代码。文章详细介绍了每种棋子的移动规则及其在程序中的实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1691

给跪了,这道题花了一天多的时间,模拟题嘛,并不难,模拟中国象棋,但是考虑不好各种情况,就容易wa了……

测试了好长时间,慢慢找到的错误。哎。做事要细心认真啊!!!

注意:

帅、士、像的初始位置以及所要到达的位置。

将和帅不能对面。

兵过河之后走向可变。

马、像的走位。


下面是AC代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int x[2],y[2];
int map[15][15];

int abs(int x){
	return x>0?x:-x;
}

int min(int a,int b){
	return a<b?a:b;
}

int max(int a,int b){
	return a>b?a:b;
}

int s(int x,int y,int bx,int by,int bxx,int byy){
	return (x<bx||x>by||y<bxx||y>byy);
}

int legal(int f,int sx,int sy,int ex,int ey){
	int mi,ma,i,j;
	int len=(sx-ex)*(sx-ex)+(sy-ey)*(sy-ey);
	if(x[0]<0||x[1]<0) return 0;
	if(s(sx,sy,1,10,1,9)||s(ex,ey,1,10,1,9)) return 0;
	if(sx==ex&&sy==ey) return 0;
	if(map[sx][sy]==0) return 0;
	if(f&&(map[sx][sy]<8||map[ex][ey]>7)) return 0; 
	if(!f&&(map[sx][sy]>7||(map[ex][ey]<8&&map[ex][ey]>0))) return 0;
	switch (map[sx][sy])
	{
	case 1:case 8:
		if( f&&(s(sx,sy,1,3,4,6)||s(ex,ey,1,3,4,6))) return 0;
		if(!f&&(s(sx,sy,8,10,4,6)||s(ex,ey,8,10,4,6))) return 0;
		if(len!=1) return 0;
		x[f]=ex,y[f]=ey;
		break;
	case 2:case 9:
		if( f&&(s(sx,sy,1,3,4,6)||s(ex,ey,1,3,4,6))) return 0;
		if(!f&&(s(sx,sy,8,10,4,6)||s(ex,ey,8,10,4,6))) return 0;
		if(len!=2) return 0;
		if(abs(sx-ex)!=1||abs(sy-ey)!=1) return 0;
		break;
	case 3:case 10:
		if(len!=8) return 0;
		if(f){
			if(sx!=1&&sx!=5&&sx!=3) return 0;
			if(sx==1||sx==5)
				if(sy!=3&&sy!=7) return 0;
			if(sx==3)
				if(sy!=1&&sy!=5&&sy!=9) return 0;
			if(ex!=1&&ex!=3&&ex!=5)return 0;
			if(ex==1||ex==5)
				if(ey!=3&&ey!=7) return 0;
			if(ex==3)
				if(ey!=1&&ey!=5&&ey!=9) return 0;
		}
		if(!f)
		{
			if(sx!=6&&sx!=8&&sx!=10) return 0;
			if(sx==6||sx==10)
				if(sy!=3&&sy!=7) return 0;
			if(sx==8)
				if(sy!=1&&sy!=5&&sy!=9) return 0;
			if(ex!=6&&ex!=8&&ex!=10)return 0;
			if(ex==6||ex==10)
				if(ey!=3&&ey!=5&&ey!=7) return 0;
			if(ex==8)
				if(ey!=1&&ey!=5&&ey!=9) return 0;
		}	
		if(map[(sx+ex)/2][(sy+ey)/2]!=0) return 0;
		break;
	case 4:case 11:
		if(len!=5) return 0;
		if(abs(sx-ex)==1){
			if(map[sx][(sy+ey)/2]!=0) return 0;
		}
		else if(abs(sy-ey)==1){
			if(map[(sx+ex)/2][sy]!=0) return 0;
		}
		else return 0;
		break;
	case 5:case 12:
		if(sx!=ex&&sy!=ey) return 0;
		if(sx==ex){
			mi=min(sy,ey),ma=max(sy,ey);
			for(i=mi+1;i<ma;i++){
				if(map[sx][i]!=0) return 0;
			}
		}
		else{
			mi=min(sx,ex),ma=max(sx,ex);
			for(i=mi+1;i<ma;i++){
				if(map[i][sy]!=0) return 0;
			}
		}
		break;
	case 6:case 13:
		if(sx!=ex&&sy!=ey) return 0;
		if(sx==ex){
			mi=min(sy,ey),ma=max(sy,ey);
			for(j=0,i=mi+1;i<ma;i++){
				if(map[sx][i]!=0)j+=1;
			}
			if(j>1) return 0;
			if(map[ex][ey]==0&&j>0) return 0;
			if(map[ex][ey]!=0&&j!=1) return 0; 
		}
		else{
			mi=min(sx,ex),ma=max(sx,ex);
			for(j=0,i=mi+1;i<ma;i++){
				if(map[i][sy]!=0) j+=1;
			}
			if(j>1) return 0;
			if(map[ex][ey]==0&&j) return 0;
			if(map[ex][ey]&&!j) return 0;
		}
		break;
	case 7:case 14:
		if(len!=1) return 0;
		if(f){
			if(sx<4) return 0;
			if(sx<6&&sy!=1&&sy!=3&&sy!=5&&sy!=7&&sy!=9) return 0;
			if(ex<sx) return 0;
			if(sx==ex&&sx<6) return 0;
		}
		else{
			if(sx>7) return 0;
			if(sx>5&&sy!=1&&sy!=3&&sy!=5&&sy!=7&&sy!=9) return 0;
			if(ex>sx) return 0;
			if(sx==ex&&sx>5) return 0;
		}
		break;
	}
	if(map[ex][ey]==1) x[0]=-1;
	if(map[ex][ey]==8) x[1]=-1;
	map[ex][ey]=map[sx][sy],map[sx][sy]=0;
	if(x[0]==x[1]){
		mi=min(y[0],y[1]),ma=max(y[0],y[1]);
		for(i=mi+1;i<ma&&map[x[0]][i]==0;i++);
		if(i==ma) return 0;
		
	}
	else if(y[0]==y[1]){
		mi=min(x[0],x[1]),ma=max(x[0],x[1]);
		for(i=mi+1;i<ma&&map[i][y[0]]==0;i++);
		if(i==ma) return 0;
	}

	return 1;
}
int main()
{
	int ncas=1,k,sx,sy,ex,ey,T,flag,i,j,n;
	scanf("%d",&T);
	while(T--)
	{
		for(i=1;i<=10;i++)
		{
			for(j=1;j<=9;j++){
				scanf("%d",&map[i][j]);
				if(map[i][j]==1) x[0]=i,y[0]=j;
				if(map[i][j]==8) x[1]=i,y[1]=j;
			}
		}
		flag=0;
		scanf("%d%d",&n,&k);

		for(i=1;i<=n;i++){
			scanf("%d%d%d%d",&sx,&sy,&ex,&ey);
			if(!flag&&!legal(k,sx,sy,ex,ey)) flag=i;
			k=!k;
		}
		
		printf("Case %d: ",ncas++);
		if(flag) printf("Illegal move on step %d\n",flag);
		else printf("Legal move\n");
	}

	return 0;
}

下面程序可以生成sample:

# include<stdio.h>
# include<string.h>
# include<stdlib.h>
# include<time.h>


int board[15][15] ;
int dp[15][15] ;
int num[] = {0, 1, 2, 2, 2, 2, 5} ;//各种棋子的数量


void select(int &x, int &y, int chs)
{
	int xx = rand() % 10 + 1 , yy = rand() % 9  + 1  ;
	int pos, mm[5][2] = {0,0,1,1,2,2,0,2,2,0} ;

	if (chs == 1 || chs == 8) //king
	{
		xx = rand()%3 + ((chs == 1) ? 8 : 1) ;
		yy = rand()%3 + 4 ;
		x = xx ;
		y = yy ;
		dp[x][y] = 1 ;
		return ;
	}
	else if (chs == 2 || chs == 9)
	{
		do{
			pos = rand()%5 ;
			xx = mm[pos][0] ;
			yy = mm[pos][1] + 4 ;
			if (chs == 2) xx += 8 ;
			else xx += 1 ;
		}while(dp[xx][yy] != 0);
		x = xx;
		y = yy ;
		dp[x][y] = 1 ;
		return ;
	}

	while (dp[xx][yy] != 0)
		xx = rand() % 10 + 1, yy = rand() % 9 + 1 ;
	dp[xx][yy] = 1 ;
	x = xx, y = yy ;
}


int main ()
{
	int T, i, j, x, y ;
	int n, k ;
	FILE *file;
	file=freopen("C:\\Users\\think\\Desktop\\in.txt","w",stdout);
	srand(time(0));
	printf ("%d\n", T = 100000) ;
	while (T--)
	{
		memset (dp, 0, sizeof(dp)) ;
		memset (board, 0, sizeof(board)) ;

		for (i = 1 ;i<= 7 ; i++)
		{
			for (j = 0 ; j < num[i] ; j++)
			{
				select(x,y, i) ;
				board[x][y] = i ;
				select(x,y, i+7) ;
				board[x][y] = i+7 ;
			}
		}
		for (i = 1 ; i <= 10 ; i++)
		{
			for (j = 1 ; j <= 9 ; j++)
			{
				if (j != 1) printf (" ") ;
				fprintf (file,"%d", board[i][j]) ;
			}
			printf ("\n") ;
		}
		fprintf (file,"%d %d\n", n=3, k = 0) ;
		while (n--)
		{
			fprintf (file,"%d %d %d %d\n", rand()%10+1,
									rand()%9+1,
									rand()%10+1,
									rand()%9+1) ;
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值