题解 P6369 [COCI2006-2007#6] MARATON

· · 题解

蒟蒻题解首祭!!!

咕了三星期了

先分析下题意: 一个由各个字母与 ‘.’ 组成的正方形矩阵(边长小于等于30)

求任意行列斜线上有没有3个连续相同的字母。

就这,无了。

思考下算法

数据范围很小(只有30),我们为什么不用最无脑的遍历枚举呢?

输入就不用多说了,一个字符型数组,但要注意声明时,冗余要稍多一些,防止访问越界。

for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
        cin>>MAP[i][j];

遍历判断: 某玩家若胜利则此玩家字母连线必定为以下四情况之一

设遍历到的这个位置坐标为(x,y)

类 型 坐标1 坐标2 坐标3
(x-1,y) (x,y) (x+1,y)
(x,y+1) (x,y) (x,y-1)
斜线 (x-1,y+1) (x,y) (x+1,y-1)
斜线 (x+1,y-1) (x,y) (x-1,y+1)

判断函数:

void JUDGE(int x,int y)
{
    if((MAP[x-1][y]==MAP[x][y])&&(MAP[x+1][y]==MAP[x][y]))
        OUT(MAP[x][y]);
    if((MAP[x][y-1]==MAP[x][y])&&(MAP[x][y+1]==MAP[x][y]))
        OUT(MAP[x][y]);
    if((MAP[x-1][y-1]==MAP[x][y])&&(MAP[x+1][y+1]==MAP[x][y]))
        OUT(MAP[x][y]);
    if((MAP[x+1][y-1]==MAP[x][y])&&(MAP[x-1][y+1]==MAP[x][y]))
        OUT(MAP[x][y]);
}

这个时候数组冗余就发挥作用了,可以略去越界判断只需要输出时进行一次特判就可以。

输出函数:

void OUT(char c)
{
    if(c!='.'&&c!=0)
    {   
        printf("%c",c);
        sign=false;
    }
}

此外,我们还需要一个sign变量(bool)记录是否有赢家,以此判断是否输出"ongoing"

if(sign)
    printf("ongoing");

完整代码(20ms,660.00KB):

#include<bits/stdc++.h>
using namespace std;

int n;
char MAP[35][35];
bool sign=true;//记录是否有赢家
void JUDGE(int,int),OUT(char);

int main()
{
    memset(MAP,0,sizeof(MAP));
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            cin>>MAP[i][j];
    for(int i=1;i<=n&&sign;i++)//循环必须判断sign情况 不然可能重复输出
        for(int j=1;j<=n&&sign;j++)
            JUDGE(i,j);
    if(sign)//若遍历后无赢家输出"ongoing"
        printf("ongoing");
    return 0;
}

void JUDGE(int x,int y)
{
    if((MAP[x-1][y]==MAP[x][y])&&(MAP[x+1][y]==MAP[x][y])) 
        OUT(MAP[x][y]);//行
    if((MAP[x][y-1]==MAP[x][y])&&(MAP[x][y+1]==MAP[x][y]))
        OUT(MAP[x][y]);//列
    if((MAP[x-1][y-1]==MAP[x][y])&&(MAP[x+1][y+1]==MAP[x][y]))
        OUT(MAP[x][y]);//斜线
    if((MAP[x+1][y-1]==MAP[x][y])&&(MAP[x-1][y+1]==MAP[x][y]))
        OUT(MAP[x][y]);//斜线
}

void OUT(char c)
{
    if(c!='.')//棋盘中可能有连续3个'.'构成的线
    {   
        printf("%c",c);
        sign=false;//更新sign
    }
}

完结撒fa~