首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

UVa 232 Crossword Answers(填字遊戲編號)問題詳解與實現

     編輯:關於C語言

UVa 232 Crossword Answers(填字遊戲編號)問題詳解與實現

給定r×c(r,c≤10)填字遊戲網格,*為黑格,字母為白格。按規則為白格編號:白格若左邊或上邊是黑格/邊界,則為橫向/縱向起始格,獲得編號。編號從1開始,掃描順序:第1行全行,第2行符合條件者,以此類推。輸出所有橫向詞(按編號遞增)與縱向詞。

編號規則形式化

對位置(i,j)(0-based),若grid[i][j] != '*'且滿足:

  • i==0 || grid[i-1][j]=='*' → 縱向起始格
  • j==0 || grid[i][j-1]=='*' → 橫向起始格

若任一條件滿足,分配下一個編號num++,記錄(i,j,num)到橫向/縱向列表。

提取單詞

  • 橫向:從(i,j)向右讀取,直到j==c-1或grid[i][j+1]=='*'。
  • 縱向:從(i,j)向下讀取,直到i==r-1或grid[i+1][j]=='*'。

C語言參考實現(AC代碼)

#include 
#include 
#include 

struct Item { int x, y, num; } across[400], down[400];
char grid[20][20];
int mark[20][20]; // 編號標記
int r, c, acCnt, downCnt, num, caseNo;

int main() {
    caseNo = 1;
    while (scanf("%d", &r) == 1 && r) {
        scanf("%d", &c);
        for (int i = 0; i < r; ++i) scanf("%s", grid[i]);
        memset(mark, 0, sizeof(mark));
        acCnt = downCnt = num = 0;
        // 掃描編號
        for (int i = 0; i < r; ++i)
            for (int j = 0; j < c; ++j)
                if (isalpha(grid[i][j])) {
                    if (i==0 || grid[i-1][j]=='*') mark[i][j] = 1;
                    if (j==0 || grid[i][j-1]=='*') mark[i][j] = 1;
                }
        // 分配編號並分類
        for (int i = 0; i < r; ++i)
            for (int j = 0; j < c; ++j)
                if (mark[i][j]) {
                    mark[i][j] = ++num;
                    if (i==0 || grid[i-1][j]=='*')
                        down[downCnt++] = {i, j, num};
                    if (j==0 || grid[i][j-1]=='*')
                        across[acCnt++] = {i, j, num};
                }
        // 輸出
        if (caseNo > 1) printf("\n");
        printf("puzzle #%d:\n", caseNo++);
        printf("Across\n");
        for (int i = 0; i < acCnt; ++i) {
            printf("%3d.", across[i].num);
            for (int j = 0;; ++j) {
                putchar(grid[across[i].x][across[i].y + j]);
                if (across[i].y + j == c-1 || grid[across[i].x][across[i].y + j + 1] == '*') break;
            }
            putchar('\n');
        }
        printf("Down\n");
        for (int i = 0; i < downCnt; ++i) {
            printf("%3d.", down[i].num);
            for (int j = 0;; ++j) {
                putchar(grid[down[i].x + j][down[i].y]);
                if (down[i].x + j == r-1 || grid[down[i].x + j + 1][down[i].y] == '*') break;
            }
            putchar('\n');
        }
    }
    return 0;
}

關鍵點總結

  • 雙重條件編號:同一白格可同時是橫向和縱向起始格,共用同一編號。
  • 掃描順序決定編號順序:行優先、列遞增,天然保證輸出列表已按編號排序。
  • 邊界即虛擬黑格:i==0視為上方黑格,j==0視為左方黑格,統一邏輯。
  • 輸出格式:%3d.右對齊編號,用例間空行,全黑格時仍輸出Across/Down標題。

本題是網格掃描與字符串提取的基礎訓練,邏輯清晰,代碼簡潔,適合入門ACM/ICPC風格題目。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved