COJ 1174 Shining Gems边界控制

这道题对枚举时限比较严,在写 check 函数时要注意边界不能超,因为超出边界有可能引用了上一组残留的数据,而使用 memset() 则会超时。

# include <stdio.h>

# define N 1005
# define DIR 4                    

const int dir[][2] = {{0,1}, {1,0}, {0,-1}, {-1,0}};

int n, m;
char b[N][N];

char check(int i, int j)
{
    char ch;
    int cnt, s;

    for (cnt = 1, s = i-2; s<i+2; ++s)
    {
        if (1<=s && s<n && b[s][j]==b[s+1][j]) ++cnt; // s <= n WA
        else cnt = 1;
        if (cnt >= 3) return 1;
    }
    for (cnt = 1, s = j-2; s<j+2; ++s)
    {
        if (1<=s && s<m && b[i][s]==b[i][s+1]) ++cnt;   // s<=m WA
        else cnt = 1;
        if (cnt >= 3) return 1;
    }

    return 0;
}

void swap(char *p, char *q)
{
    char ch;

    ch = *p, *p = *q, *q = ch;
}

char solve(void)
{
    char ok;
    int i, j, ni, nj, d;

    ok = 0;

    for (i = 1; i <= n; ++i)
    {
        for (j = 1; j <= m; ++j)
        {
            for (d = 0; d < DIR; ++d)
            {
                if (check(i, j))
                {
                    return 1;
                }
                ni = i + dir[d][0];
                nj = j + dir[d][1];
                if (1<=ni && ni<=n && 1<=nj && nj<=m)
                {
                    swap(&b[i][j], &b[ni][nj]);
                    if (check(ni,nj))
                    {
                        ok = 2;
                    }
                    swap(&b[i][j], &b[ni][nj]);
                }
            }
        }
    }

    if (ok) return 2;
    return 3;
}

int main()
{
    int ok;
    int i, j;

    while (~scanf("%d%d", &n, &m))
    {
        for (i = 1; i <= n; ++i) scanf("%s", b[i]+1);
        switch(solve())
        {
            case 1:printf("Combo\n");break;
            case 2:printf("Enjoy It\n");break;
            case 3:printf("Game Over\n");break;
        }
    }

    return 0;
}

//

原文地址:https://www.cnblogs.com/JMDWQ/p/2582443.html