G 跳马棋 2019浙江理工大学新生赛

这是一道关于跳马棋游戏的编程问题,棋盘为8*8,每方有一个马,玩家交替走棋,目标是走到对方棋子的位置获胜。输入给出两个马的起始位置,需要计算赢的概率,概率低于10^-6视为平局。解题思路涉及奇偶性判断和广度优先搜索。

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

1832: 跳马棋

时间限制: 1 Sec  内存限制: 128 MB

题目描述

重新装修完后,丁总非常兴奋的领着快码佳编四兄弟姐妹去参观他们的游戏。 
他们正在开发一款棋类游戏。这款游戏的规则如下: 
在一个8*8的国际象棋棋盘上,一个玩家用白马,另外一个玩家用黑马。两个玩家交替下棋,白棋先下。在每次下的时候,马从现有位置随机走到一个有效位置。有效位置指的是棋盘里,在某个坐标轴移动2步另外一个坐标轴移动一步(即马的走法)。所有有效位置上能移到是等概率的。当一个棋手将马移到一个对方已经占有的格子上时,该棋手就赢了(俗称吃了对方)。 
为了吸引玩家的兴趣,当马在2个给定的起始位置时,我们就要计算出赢的概率。如果双方赢的概率小于10-6时我们认为是平局。 

输入

第一行输入2个整数A和B(1<=A,B<=8)代表白马开始的位置 
第二行输入2个整数C和D(1<=C,D<=8)代表黑马开始的位置 

输出

输出谁有更高概率赢,白赢输出“white”,黑输出“black”,如果是平局,则输出“draw”

 

样例输入

【样例输入1】
1 1
4 7
【样例输入2】
1 1
8 8

样例输出

【样例输出1】
white
【样例输出2】
black

这题很多人都是用奇偶性做的:

#include<bits/stdc++.h> 
using namespace std;
int main()
{
	int a,b,c,d;
	scanf("%d%d%d%d",&a,&b,&c,&d);
	int tmpx=abs(a-c);
	int tmpy=abs(b-d);
	//if((tmpx<1)||tmpy<1&&(tmpx==1&&tmpy==1))printf("draw\n");
	if((tmpx+tmpy)%2!=0)printf("white\n");
	else printf("black\n");
}

其实最基本的做法是用两个队列进行宽搜

#include<bits/stdc++.h> 
#define fr(i,x,y) for(int i=x;i<=y;i++)
using namespace std;
const int MAXN=10;
struct node
{
	int x,y;
	int t;
};
queue<node>q1,q2;
int a[MAXN][MAXN],b[MAXN][MAXN];
int zbx[8]={-1,1,2,2,1,-1,-2,-2};
int zby[8]={2,2,1,-1,-2,-2,-1,1};
int main()
{
	int wx,wy,bx,by;
	cin>>wx>>wy>>bx>>by;
	q1.push((node){wx,wy,0});a[wx][wy]=1;
	q2.push((node){bx,by,0});b[bx][by]=1;
	fr(o,1,1000000)
	{
		while(!q1.empty())
		{
			node tmp=q1.front();
			if(tmp.t==o)break;
			q1.pop();
			a[tmp.x][tmp.y]=0;
			fr(o,0,7)
			{
				int xx=tmp.x+zbx[o];
				int yy=tmp.y+zby[o];
				if(xx<=0||yy<=0||xx>8||yy>8)continue;
				a[xx][yy]=1;
				if(b[xx][yy])
				{
					printf("white\n");
					return 0;
				}
				q1.push((node){xx,yy,tmp.t+1});
			}
		}
		while(!q2.empty())
		{
			node tmp=q2.front();
			if(tmp.t==o)break;
			q2.pop();
			b[tmp.x][tmp.y]=0;
			fr(o,0,7)
			{
				int xx=tmp.x+zbx[o];
				int yy=tmp.y+zby[o];
				if(xx<=0||yy<=0||xx>8||yy>8)continue;
				b[xx][yy]=1;
				if(a[xx][yy])
				{
					printf("black\n");
					return 0;
				}
				q2.push((node){xx,yy,tmp.t+1});
			}
		}
	}
	printf("draw\n");
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值