列表

详情


NC16136. 黑白棋

描述

端午节前夕,铁子和顺溜二人聊到了黑白棋,黑白棋是一个历史悠久的益智游戏,但是双方都觉得自己比较厉害谁也不服谁,然后开始了黑白棋探讨之旅,但是谁也没想到在一边观战的城哥拥有着一个预知未来的能力,能准确预知未来下子的位置(x,y),由于能力有限,却不能得知每个回合落子的颜色,但是能根据落子的位置判断是黑方还是白方,现在城哥想知道最后黑白双方的棋子比例是多少。(黑方先手)

------分割线-------------------------------------------------------------

下面是黑白棋规则介绍:

这张图片是黑白棋的标准开局图,每局由执黑色棋玩家先下子,交互下子。直到游戏结束!

棋盘为8×8的方格布局,开局时在棋盘正中有摆好的四枚棋子,黑白各2枚,交叉放置,由执黑棋的一方先落子,双方交替下子,棋子落在方格内,一局游戏结束后双方更换执子颜色。

合法的棋步包括:在一个空格新落下一个棋子,并且翻转对手一个或多个棋子。
下子方式:把自己颜色的棋子放在棋盘的空格上,而当自己放下的棋子在横、竖、斜八个方向内有一个自己的棋子,则被夹在中间的对方棋子全部翻转会成为自己的棋子。夹住的位置上必须全部是对手的棋子,不能有空格。并且,只有在可以翻转棋子的地方才可以下子。
一步棋可以在数个方向上翻棋,任何被夹住的棋子都必须被翻转过来,棋手无权选择不去翻某个棋子必须是刚下的子夹对方才能够翻对方的子,因翻转对方的棋子而夹住的子是不能被翻的。
翻转棋子时,每次下子最少必须翻转对方一个棋子,若棋局中下子都不能翻转对方棋子,则自动pass轮空,己方无子可下,由对方继续下子。两个玩家都不能下子翻转对方棋子,游戏结束。

输入描述

每行两个数字x,y代表落子坐标(1 ≤ x,y ≤ 8)

以EOF结束下子,保证下子的正确性以及合法性,下完最后一颗子代表棋局结束。

ps:emmmm... 貌似有点长,不要慌,问题不大(雾

输出描述

输出一行,黑方与白方的棋子数量之比a:b

示例1

输入:

3 4
5 3
6 5
3 5
5 2
7 5
7 6
7 7
8 7
2 3
7 8
5 1
7 4
8 5
4 3
7 3
2 4
2 5
4 2
3 1
1 6
6 3
2 2
1 4
4 6
2 6
1 3
3 3
6 4
3 7
6 2
7 1
8 6
8 8
5 7
2 1
4 1
5 6
1 5
4 7
8 3
6 6
6 7
8 4
1 1
5 8
6 1
3 2
8 1
6 8
3 8
3 6
1 2
8 2
4 8
7 2
2 7
1 7
2 8
1 8

输出:

28:36

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 3ms, 内存消耗: 492K, 提交时间: 2020-05-16 13:57:50

#include<bits/stdc++.h>
using namespace std;
 
int i,j,x,y,t=1,a=0,b=0,v[11][11];
int d[8][2]={1,0,-1,0,1,1,1,-1,0,1,0,-1,-1,-1,-1,1};
bool slove(int x,int y,int s)
{
    int X,Y,f=0;
    for(int i=0;i<8;i++)
    {
        X=x+d[i][0],Y=y+d[i][1];
        if(v[X][Y]!=(!s))continue;
        while(v[X+d[i][0]][Y+d[i][1]]==(!s))X+=d[i][0],Y+=d[i][1];
        if(v[X+d[i][0]][Y+d[i][1]]==s)
        {
            X=x+d[i][0],Y=y+d[i][1];
            v[X][Y]=s,f=1;
            while(v[X+d[i][0]][Y+d[i][1]]==(!s))X+=d[i][0],Y+=d[i][1],v[X][Y]=s;
        }
    }
    return f;
}
int main()
{
    memset(v,-1,sizeof v);
    v[4][4]=v[5][5]=0,v[5][4]=v[4][5]=1;
    while(~scanf("%d%d",&x,&y))
    {
        if(slove(x,y,t))v[x][y]=t,t=!t;
        else if(slove(x,y,!t))v[x][y]=!t;
        else break;   
    }
    for(i=1;i<=8;i++)
        for(j=1;j<=8;j++)
        {
            if(v[i][j]==1)a++;
            else if(v[i][j]==0)b++;
        }
    printf("%d:%d\n",a,b);
    return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 3ms, 内存消耗: 488K, 提交时间: 2020-03-11 19:15:37

#include<bits/stdc++.h>
using namespace std;
int v[11][11];
int d[8][2]={1,0,-1,0,1,1,1,-1,0,1,0,-1,-1,-1,-1,1};
bool slove(int x,int y,int s)
{
	bool flag=0;
	for(int i=0;i<8;i++)
	{
		int tx=x+d[i][0];
		int ty=y+d[i][1];
		if(v[tx][ty]!=(!s))
		continue;
		while(v[tx+d[i][0]][ty+d[i][1]]==(!s))
		tx+=d[i][0],ty+=d[i][1];
		if(v[tx+d[i][0]][ty+d[i][1]]==s)
		{
			tx=x+d[i][0];
			ty=y+d[i][1];
			v[tx][ty]=s;
			while(v[tx+d[i][0]][ty+d[i][1]]==(!s))
			tx+=d[i][0],ty+=d[i][1],v[tx][ty]=s;
			flag=1;
		}
	}
	return flag;
}
int main()
{
	memset(v,-1,sizeof v);
	v[4][4]=v[5][5]=0;
	v[5][4]=v[4][5]=1;
	int x,y,t;
	t=1;
	while(~scanf("%d%d",&x,&y))
	{
		if(slove(x,y,t))
		v[x][y]=t,t=!t;
		else
		if(slove(x,y,!t))
		v[x][y]=!t;
		else
		break;
	}
	int h,b;
	h=b=0;
	for(int i=1;i<=8;i++)
	for(int j=1;j<=8;j++)
	if(v[i][j]==1)
	h++;
	else
	if(v[i][j]==0)
	b++;
	printf("%d:%d\n",h,b);
	return 0;
}

上一题