1. 程式人生 > >CCF NOI1054 掃雷遊戲

CCF NOI1054 掃雷遊戲


時間限制: 1000 ms  空間限制: 262144 KB

題目描述

  掃雷遊戲是一款十分經典的單機小遊戲。它的精髓在於,通過已翻開格子所提示的周圍格地雷數,來判斷未翻開格子裡是否是地雷。
  現在給出n行m列的雷區中的地雷分佈,要求計算出每個非地雷格的周圍格地雷數。
  注:每個格子周圍格有八個:上、下、左、右、左上、右上、左下、右下。

輸入

第一行包含兩個整數n和m,分別表示雷區的行數和列數。1 <= n <= 100, 1 <= m <= 100。
  接下來n行,每行m個字元,‘*’表示相應格子中是地雷,‘?’表示相應格子中無地雷。字元之間無任何分隔符

輸出

  n行,每行m個字元,描述整個雷區。若相應格中是地雷,則用‘*’表示,否則用相應的周圍格地雷數表示。字元之間無任何分隔符。

樣例輸入

3 3
*??
???
?*?
樣例輸出

*10
221
1*1

資料範圍限制

  1 <= n <= 100, 1 <= m <= 100。


問題分析

  掃雷遊戲是人們熟知的一個計算機遊戲,通過這個程式,可以瞭解其區域性的計算是如何實現的。

  這是一個簡單的計算問題,對於一個位置,直接計算其周圍的地雷數量即可。

程式說明

  定義二維陣列用於儲存掃雷遊戲的棋盤時,周圍多出一圈,可以省去陣列下標的越界判定。

  這裡給出兩種計算地雷數量的方法,分別編寫程式。

要點詳解 先定義一個符號常量,再用它來定義二維陣列,可以使得程式的通用性得到提高一些程式設計技巧有助於簡化程式的程式碼
函式memset()用於給大量的儲存空間設定初始值是方便的。陣列around[]儲存周圍元素的相對下標,使得無序變有序,可以用迴圈來處理。
參考連結:(略)。

100分通過的C語言程式之一:

#include <stdio.h>
#include <string.h>

struct _around {
    int drow;
    int dcol;
} around[] = {{-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}};
#define AN 8

#define N 100
char a[N+2][N+2];

int main(void)
{
    int n, m, i, j, k;

    memset(a, 0, sizeof(a));

    scanf("%d%d", &n, &m);
    for(i=1; i<=n; i++)
        scanf("%s", a[i]+1);

    for(i=1; i<=n; i++) {
        for(j=1; j<=m; j++) {
            int count = 0;
            if(a[i][j] == '*')
                printf("%c", a[i][j]);
            else {
                for(k=0; k<AN; k++)
                    if(a[i + around[k].drow][j + around[k].dcol] == '*')
                        count++;
                printf("%d", count);
            }
        }
        printf("\n");
    }
    return 0;
}

100分通過的C語言程式之二:

#include <stdio.h>

struct _around {
    int drow;
    int dcol;
} around[] = {{-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}};
#define AN 8

#define N 100

char a[N+2][N+2];

int main(void)
{
    int n, m, i, j, k;

    scanf("%d%d", &n, &m);
    for(i=1; i<=n; i++)
        scanf("%s", a[i]+1);

    for(i=1; i<=n; i++)
        for(j=1; j<=m; j++)
            if(a[i][j] != '*')
                a[i][j] = 0;

    for(i=1; i<=n; i++)
        for(j=1; j<=m; j++)
            if(a[i][j] == '*')
                for(k=0; k<AN; k++)
                    if(a[i + around[k].drow][j + around[k].dcol] != '*')
                        a[i + around[k].drow][j + around[k].dcol]++;

    for(i=1; i<=n; i++) {
        for(j=1; j<=m; j++)
            if(a[i][j] == '*')
                printf("%c", a[i][j]);
            else
                printf("%d", a[i][j]);
        printf("\n");
    }

    return 0;
}

/*
4 4
?**?
*?**
????
??*?
2**3
*4**
1333
01*1
*/