题目描述
一个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;
}