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;
}