ccsp五子棋

五子棋(wuzi)

 

【题目描述】

五子棋是世界智力运动会竞技项目之一,是一种两人对弈的纯策略型棋类游戏。通   常双方分别使用黑白两色的棋子,下在棋盘直线与横线的交叉点上,先形成五子连珠者   获胜。

五子连珠是在横. 线. ,纵. 线. ,斜. 线. ,反. . 线. 四个方向上形成五. . . . . 的连线,当出现多于五子的连珠时,也只记为一. . 五子连珠。

. . . . . . 等于棋局中的所有方向上的五子连珠连线的数量之和。

我们想知道,给定一个长宽皆为 n 的棋局,白. . 落在哪些点可以增. . . . . . .

. . .

对增. . . . . . . . . . 的举例说明 (A 点为我们选择的落点): 1

 

wwwwAbbbb

 

落白棋之前未形成五子连珠,落入白棋之后,五子连珠总数加一,满足要求。

2

 

wwwwwAbbbb

 

落白棋之前已经形成五子连珠,落白棋之后,五子连珠总数不变,不满足要求。

3

 

wwwwwAwwwww

 

落白棋之前五子连珠总数为二,落入白棋之后,两边连成一线,五子连珠总数减  一,不满足要求。

4

 

*w***w*****

**w**w*****

***w*w*****

****ww***** wwwwwAwwwww

 

落白棋之前五子连珠总数为二。落入白棋之后,两边连成一线,斜向和纵向形成新  的五子连珠,总数为三。五子连珠总数加一,这个点满足要求。

 

 

【输入格式】

从标准输入读入数据。

输入为第一行为一个数字 nn ≤ 40),表示棋盘大小。

接下来的 n 行,每行为 n 个字符,可能有三种字符,* 表示无棋子,b 表示黑棋,

w 表示白棋。

输入棋局中可能已. . . . . . . 的情况,我们需要计算能增. . . . . . . . . . 的白棋落点。

 

【输出格式】

输出到标准输出。

输出为 k 行,包括 k 个满足要求的落点,k 个点按照从. . . . ,从. . . . 的顺序输出,即先按行排序,再按列排序输出。

每行为一个点坐标 x y,分别表示列坐标,行坐标,以空格分隔,坐标序号从 0 开始,棋盘左上角为原点。

 

*a***

*****

*****

*****

***b*

 

图中 a 点的坐标为 1 0,b 点的坐标为 3 4。

 

【样例输入】

 

8

****b*bb

*****b*b bb*bbbw* w*wbwwww bwwbwwbw ww**wbbw

*bww***w

***bwb*b

 

 

【样例输出】

 

7 2

2 5

3 5

4 6

2 7

 

【子任务】

 

测试点

说明

1,2

没有满足要求的点

3,4,5,6,7,8

只需要计算横纵方向, 棋局中不存在旧的五子连珠

9,10,11,12,13,14

需要计算所有方向, 棋局中不存在旧的五子连珠

15,16,17,18,19,20

盘面上存在旧的五子连珠

自己写了一遍,也不知道对不对,ccsp简直了,题解都木有

#include 
#include 
using namespace std;

#define MAX_N 43

char q[MAX_N][MAX_N];
int heng[MAX_N][MAX_N];
int zong[MAX_N][MAX_N];
int xie[MAX_N][MAX_N];
int fanxie[MAX_N][MAX_N];
int n;

//右
bool heng_(int i,int y)
{
    if(y+5>n) return false;
   // printf("\n");
    for(int j = y; j < n; j++){
       // printf("%c",q[i][j]);
        if((q[i][j]!='w'||heng[i][j]) && j < y+5) return false;
    }
   // printf("\n");
    for(int j = y; j < n; j++){
        if(q[i][j]=='w') heng[i][j] = 1;
        else break;
    }
    //printf("heng:x=%d,y=%d\n",i,y);
    return true;
}

//右下
bool fanxie_(int x,int y)
{
    if(x+5>n||y+5>n) return false;
    for(int i = x,j = y; i < n && j < n; i++,j++){
        if((q[i][j]!='w'||fanxie[i][j]) && i < x+5) return false;
    }
    for(int i = x,j = y; i < n && j < n; i++,j++){
        if(q[i][j]=='w') fanxie[i][j] = 1;
        else break;
    }
   // printf("fanxie:x=%d,y=%d\n",x,y);
    return true;
}

//下
bool zong_(int x,int j)
{
    if(x+5>n) return false;
    for(int i = x; i < n; i++){
        if((q[i][j]!='w'||zong[i][j]) && in||y-5<-1) return false;
    for(int i = x,j = y; i < n && j >= 0; i++,j--){
        if((q[i][j]!='w'||xie[i][j]) && i < x+5) return false;
    }
    for(int i = x,j = y; i < n && j >= 0; i++,j--){
        if(q[i][j]=='w') xie[i][j] = 1;
        else break;
    }
   // printf("xie:x=%d,y=%d\n",x,y);
    return true;
}

//计算五子连珠数
int fun()
{
    //初始化
    for(int i = 0; i < n; i++){
        for(int j = 0; j < n; j++){
            heng[i][j] = 0;
            zong[i][j] = 0;
            xie[i][j] = 0;
            fanxie[i][j] = 0;
        }
    }
    int ans = 0;
    for(int i = 0; i < n; i++){
        for(int j = 0; j < n; j++){
            if(q[i][j]=='w'){
                if(heng_(i,j)) ans++;
                if(fanxie_(i,j)) ans++;
                if(zong_(i,j)) ans++;
                if(xie_(i,j)) ans++;
            }
        }
    }
    //cout <<"ans="<> n;
    for(int i = 0; i < n; i++){
        getchar();
        for(int j = 0; j < n; j++){
            scanf("%c",&q[i][j]);
        }
    }
    cnt = fun();
    for(int i = 0; i < n; i++){
        for(int j = 0; j < n; j++){
            if(q[i][j]=='*'){
                q[i][j] = 'w';
                //printf("%d %d\n",i,j);
                if(fun() > cnt)
                    printf("%d %d\n",j,i);
                q[i][j] = '*';
            }
        }
    }
    return 0;
}

//test样例
//8
//****b*bb
//*****b*b
//bb*bbbw*
//w*wbwwww
//bwwbwwbw
//ww**wbbw
//*bww***w
//***bwb*b


 

你可能感兴趣的:(ccsp)