洛谷:B3783 [语言月赛202306] 棋

时间限制1.00s         内存限制512.00MB         难易度:普及−

【题目描述】

zyl 和「她」在 n×m 的格子纸上下五子棋。「她」总是先手

现在你会得知以下信息:

  • 格子纸的大小 n,m,代表棋盘共 n 行 m 列。
  • n 个仅由字符 ~*$ 构成的长度为 m 的字符串(即 n×m 个字符)。对于第 i 个字符串的第 j 个字符,~ 表示第 i 行第 j 列的格子是空的,* 表示「她」已经在这一格落下棋子,$ 表示 zyl 已经在这一格落下棋子。

类似于五子棋的基本规则,一局棋局由「先手」开始,双方轮流落子。如果有同一行,同一列,或者同一 45° 斜对角线有同一方连续五个棋子,那这一方便是胜者。

现在,请你以以下方式判断当前的棋局:如果已有一方获胜,请你判断是哪一方获胜。否则,请你判断当前轮到哪一方落子。

【输入格式】

输入共 n + 1 行。

第一行两个整数 n,m,表示格子纸的大小。
接下来 n 行,每行一个长度为 m 的,仅由字符 ~、 *$ 组成的字符串,代表棋局的情况。

输出格式

输出共一行一个字符串或一个字符,表示棋局的情况。

  • 如果已有一方获胜,输出一个字符串 Pleasing! 或 zylwins!Pleasing! 表示「她」获胜,zylwins! 表示 zyl 获胜。
  • 否则,输出一个字符 W 或 ZW 表示当前轮到「她」落子,Z 表示轮到 zyl 落子。

【输入输出样例】

输入 #1

5 5
~~*~$
***~~
~$*~~
~~*~$
$$*$~

输出 #1

Pleasing!

【说明/提示】

样例 1 解释

在第三列有连续的五个 *,所以「她」获胜了。

数据规模与约定

对于前 40% 的数据,保证没有任何一方获胜。

对于 100% 的数据, 5≤n,m≤30,字符串仅由 ~*# 组成,而且不会出现任意同一行,同一列或是同一 45° 斜对角线上有连续 6 个或以上连续且相同的 * 或 #,并且最多只有一条连续的 5 个 * 或 $。 * 的总数不小于 $ 的总数,且至多比 $ 的总数大 1。保证输入的字符串至少存在一个字符 ~

【算法分析】

对于这道题,判断该谁落子比较简单,只需记录 * 和 $ 的数量,如果相等,则说明一个回合恰好结束,应该轮到先手落子。反之,* 的数量比 $ 的数量多一,则该轮到后手即 zyl 落子。

至于是否有人胜利,如果写一堆判断语句会和麻烦,我们可以开两个数组 dx 和 dy 分别存储每个方向相邻棋子对应的横、纵坐标的差值。判断胜负时,我们每次将坐标加上这两个差值,看新坐标的棋子是否和原坐标上的棋子一样,重复 4 遍即可。

【参考代码】

#include <bits/stdc++.h>
using namespace std;
int dx[4]={0,1,-1,1};
int dy[4]={1,0,1,1};
char c[35][35];
int n,m,l,r;
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>(c[i]+1);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            if(c[i][j]=='~') continue;
            l+=c[i][j]=='*';
            r+=c[i][j]=='$';
            for(int k=0;k<4;k++)
            {
                int x=i,y=j;
                bool f=1;
                for(int t=1;t<=4;t++)
                {
                    x+=dx[k];
                    y+=dy[k];
                    if(x<1||y<1||x>n||y>m)
                    {
                        f=0;
                        break;
                    }
                    if(c[x][y]!=c[i][j])
                    {
                        f=0;
                        break;
                    }
                }
                if(f==1)
                {
                    if(c[i][j]=='*')
                    {
                        cout<<"Pleasing!";
                        return 0;
                    }
                    else{
                        cout<<"zylwins!";
                        return 0;
                    }
                }
            }
        }
    if(l==r) cout<<"W";
    else cout<<"Z";
    return 0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值