xtu oj 黑棋和白棋

题目描述

一个n×n格棋盘,某些格子里放了黑棋或者白棋,按行,列,对角方向,数棋子。如果同颜色同方向的连续的棋子达到3个或者以上,我们称之为“杠”。 注意如果有3个以上的同色连续棋子,并不会算成多条“杠”,只会算为一条。比如有4个黑棋连成一行,这时这4颗黑棋只算一条杠。请计算一下棋盘上黑棋和白棋都有多少条“杠”?

输入格式

第一行是一个整数T (1≤T≤100),表示样例的个数。

以后每个样例的第一行是一个整数n (3≤n≤15),表示棋盘的大小。

以后的n行,每行n个字母,表示棋盘的格子的情况。字母只含B,W,.,分别表示黑棋,白棋,空格。

输出格式

依次输出每个样例的结果,每个样例输出一行,为两个整数,表示棋局中黑棋和白棋的杠的数量,两者用一个空格隔开。

样例输入

2
4
BBBB
W...
WW..
W.W.
3
WWW
WWW
WWW

样例输出

1 2
0 8

样例解释

黑棋只有第一行的4颗组成一条杠; 白棋从(2,1)出发,往下,和往右下的组成2条杠。

第二个样例白棋三横三竖两个对角,一共8个。

思路:

从一个坐标开始遍历该坐标为起点的一行,一列和两对角线,为了简化遍历条件判断,将二维数组开到20,防止遍历时越界,只需要比较与当前坐标为起点相邻的2个值,为了避免3个以上连续字母重复计数,如果该坐标在该方向前值相同,将数目cnt置为0;

每次需要将数组重新置0;

代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
    int t;
    scanf("%d",&t);
    char s[20][20];
    char c[2] = {'B','W'};
    int cout[2] ={0,0};//记录black和white的个数
    while(t--){
        memset(s,0,sizeof(s));//多案例必须每次置零防止上一次遗留
        memset(cout,0,sizeof(cout));
        int n;
        scanf("%d",&n);
//      for(int i=1;i<=n;i++){
//          for(int j = 1;j<=n;j++){
//              scanf(" %c",&s[i][j]);//前加上空格表示跳过换行
//          }
//      }
        for(int i=1;i<=n;i++)
            scanf("%s",s[i]+1);
     
        for(int i=1;i<=n;i++){//统计每一行
            for(int j = 1;j<=n;j++){
                for(int k=0;k<2;k++){
                    int cnt = 0;
                    if(s[i][j]==c[k])//起点
                    {
                        if(s[i][j+1] == c[k])//计算每行
                            cnt++;
                        if(s[i][j+2] == c[k])
                            cnt++;
                        if(s[i][j-1] == c[k])
                            cnt = 0;//已经存在3个,已经计数
                        if(cnt==2)
                            cout[k]++;
                        cnt = 0;
                        if(s[i+1][j] == c[k])//计算每列
                            cnt++;
                        if(s[i+2][j] == c[k])
                            cnt++;
                        if(s[i-1][j] == c[k])
                            cnt = 0;//已经存在3个,已经计数
                        if(cnt==2)
                            cout[k]++;
                        cnt = 0;
                        if(s[i+1][j+1] == c[k])//主对角线
                            cnt++;
                        if(s[i+2][j+2] == c[k])
                            cnt++;
                        if(s[i-1][j-1] == c[k])
                            cnt = 0;//已经存在3个,已经计数
                        if(cnt==2)
                            cout[k]++;
                        cnt = 0;
                        if(s[i+1][j-1] == c[k])//次对角线
                            cnt++;
                        if(s[i+2][j-2] == c[k])
                            cnt++;
                        if(s[i-1][j+1] == c[k])
                            cnt = 0;//已经存在3个,已经计数
                        if(cnt==2)
                            cout[k]++;
                        cnt = 0;
                    }
                }
            }
        }
            printf("%d %d\n",cout[0],cout[1]);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值