XTU-OJ 《C语言程序设计》 1440-黑棋和白棋

题目描述

一个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个。

模拟+暴力,没难度,就是有些麻烦,所以就贴个代码供参考、对拍吧。

AC代码:

        我的,但是写的太麻烦了,属于一步一步把所有问题都想进去了。后面再贴个我哥们的极简代码,大道至简,暴力题,就是要用纯暴力,管他什么细节。

#include <stdio.h>

// 黑棋:0; 白棋:1
int T,n,ans[5];
int chess[20][20];
char Chess[20][20];

void heng()                                 // 横
{
    int flag,cnt,i,j;  
    for ( i = 1; i <= n; i ++)
    {
        flag = chess[i][1],cnt=1;
        for ( j = 2; j <= n; j ++)
        {
            if (flag == chess[i][j])    cnt ++;
            else
            {
                if (cnt >= 3)           ans[flag] ++;
                flag = chess[i][j];
                cnt = 1;
            }
        }
        if (cnt >= 3)                   ans[flag] ++;
    }
}

void shu()                                      // 竖
{
    int flag,cnt,i,j;    
    for ( i = 1; i <= n; i ++)            
    {
        flag = chess[1][i],cnt=1;
        for ( j = 2; j <= n; j ++)
        {
            if (flag == chess[j][i])    cnt ++;
            else
            {
                if (cnt >= 3)           ans[flag] ++;
                flag = chess[j][i];
                cnt = 1;
            }
        }
        if (cnt >= 3)                   ans[flag] ++;
    }
}

void xieshun()                                      // 斜顺
{
    int flag,flag1,flag2,cnt,cnt1,cnt2,i,j,k;
    i = j = cnt = 1;
    flag = chess[i][j];
    while (i < n)
    {
        i ++, j ++;
        if (flag == chess[i][j])       cnt++;
        else
        {   
            if (cnt >= 3)              ans[flag] ++;
            flag = chess[i][j];
            cnt = 1;
        }
    }
    if (cnt >= 3)              ans[flag] ++;

    for (k = 2; k <= n-2; k ++)
    {
        i = k,j = 1;
        cnt1 = cnt2 = 1;
        flag1 = chess[k][1],flag2 = chess[1][k];
        while ( i < n)
        {
            i ++,j ++;
            if (flag1 == chess[i][j])       cnt1++;
            else
            {   
                if (cnt1 >= 3)              ans[flag1] ++;
                flag1 = chess[i][j];
                cnt1 = 1;
            }

            if (flag2 == chess[j][i])       cnt2++;
            else
            {
                if (cnt2 >= 3)              ans[flag2] ++;
                flag2 = chess[j][i];
                cnt2 = 1;
            }
        }
        if (cnt1 >= 3)                   ans[flag1] ++;
        if (cnt2 >= 3)                   ans[flag2] ++;
    }
}

void xieni()                                      // 斜逆
{
    int flag,flag1,flag2,cnt,cnt1,cnt2,i,j,k,p,s,t;
    i = 1, j = n,cnt = 1;
    flag = chess[i][j];
    while (i < n)
    {
        i ++, j --;
        if (flag == chess[i][j])       cnt++;
        else
        {   
            if (cnt >= 3)             ans[flag] ++;
            flag = chess[i][j];
            cnt = 1;
        }
    }
    if (cnt >= 3)                      ans[flag] ++;

    p = 2;
    for ( k = n-1; k >= 3; k --, p ++)
    {
        i = 1, j = k;
        s = p, t = n;
        flag1 = chess[i][j];
        flag2 = chess[s][t];
        cnt1 = cnt2 = 1;
        while ( j > 1)
        {
            i ++, j --;  s ++, t --;
            if (flag1 == chess[i][j])       cnt1++;
            else
            {   
                if (cnt1 >= 3)              ans[flag1] ++;
                flag1 = chess[i][j];
                cnt1 = 1;
            }

            if (flag2 == chess[s][t])       cnt2++;
            else
            {
                if (cnt2 >= 3)              ans[flag2] ++;
                flag2 = chess[s][t];
                cnt2 = 1;
            }
        }
            if (cnt1 >= 3)                   ans[flag1] ++;
            if (cnt2 >= 3)                   ans[flag2] ++;
    }
}

int main()
{
    scanf("%d",&T);
    while ( T -- )
    {
        scanf("%d",&n);
        ans[0] = ans[1] = 0;
        for (int i = 1; i <= n; i ++)
            scanf("%s",Chess[i]+1);
        for (int i = 1; i <= n; i ++)
        {
            for (int j = 1; j <= n; j ++)
            {
                if (Chess[i][j] == 'B')          chess[i][j] = 0;
                else if (Chess[i][j] == 'W')     chess[i][j] = 1;
                else if (Chess[i][j] == '.')     chess[i][j] = 2;
            }
        }
        heng();
        shu();
        xieshun();
        xieni();
        printf("%d %d\n",ans[0],ans[1]);
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string.h>
using namespace std;
char str[20][20],ch[3]={'0','W','B'},ct[3]={1};
void solve(){
    int n; scanf("%d",&n);
    for(int i = 1; i <= n; i ++) scanf("%s",str[i] + 1);
    for(int i = 1; i <= n; i ++){
        for(int j = 1; j <= n; j ++){
            for(int k = 1; k <= 2; k ++){
                int cnt = 0;
                if(str[i][j] == ch[k]){
                    if(str[i][j] == str[i][j+1]) cnt ++;
                    if(str[i][j] == str[i][j+2]) cnt ++;
                    if(str[i][j] == str[i][j-1]) cnt = 0;
                    if(cnt == 2) ct[k] ++; cnt = 0;
                    if(str[i][j] == str[i+1][j]) cnt ++;
                    if(str[i][j] == str[i+2][j]) cnt ++;
                    if(str[i][j] == str[i-1][j]) cnt = 0;
                    if(cnt == 2) ct[k] ++; cnt = 0;
                    if(str[i][j] == str[i+1][j+1]) cnt ++;
                    if(str[i][j] == str[i+2][j+2]) cnt ++;
                    if(str[i][j] == str[i-1][j-1]) cnt = 0;
                    if(cnt == 2) ct[k] ++; cnt = 0;
                    if(str[i][j] == str[i+1][j-1]) cnt ++;
                    if(str[i][j] == str[i+2][j-2]) cnt ++;
                    if(str[i][j] == str[i-1][j+1]) cnt = 0;
                    if(cnt == 2) ct[k] ++; cnt = 0;
                }
            }
        }
    }
    printf("%d %d\n",ct[2],ct[1]);
}
int main(){
    int T; scanf("%d",&T);
    while(T --> 0) solve(),memset(str,0,sizeof(str)),memset(ct,0,sizeof(ct));
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值