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;

}

//

你可能感兴趣的:(gem)