C3-UVa232-Crossword Answers

Posted on 2020-06-28 10:34  lemonforce  阅读(125)  评论(0编辑  收藏  举报

平台:

UVa Online Judge

題號:

1225 - Digit Counting

題目連結:

q

題目說明:

输入一个r行c列(1≤r,c≤10)的网格,黑格用“*”表示,每个白格都填有一个字母。如果一个白格的左边相邻位置或者上边相邻位置没有白格(可能是黑格,也可能出了网格边界),则称这个白格是一个起始格。
首先把所有起始格按照从上到下、从左到右的顺序编号为1, 2, 3,…,如图3-7所示。

 

接下来要找出所有横向单词(Across)。这些单词必须从一个起始格开始,向右延伸到一个黑格的左边或者整个网格的最右列。最后找出所有竖向单词(Down)。这些单词必须从一个起始格开始,向下延伸到一个黑格的上边或者整个网格的最下行。

範例輸入:

2 2
AT
*O
6 7
AIM*DEN
*ME*ONE
UPON*TO
SO*ERIN
*SA*OR*
IES*DEA
0

範例輸出:

puzzle #1:
Across
1.AT
3.O
Down
1.A
2.TO
puzzle #2:
Across
1.AIM
4.DEN
7.ME
8.ONE
9.UPON
11.TO
12.SO
13.ERIN
15.SA
17.OR
18.IES

19.DEA
Down
1.A
2.IMPOSE
3.MEO
4.DO
5.ENTIRE
6.NEON
9.US
10.NE
14.ROD
16.AS
18.I
20.A

解題方法:

Across相对于Down输出要简单。本以为要写2个函数,但后来发现其实可以合并在一起。

程式碼:

  1 #include <cstdio>
  2 #include <cstring>
  3 
  4 const int MAXN = 15;
  5 
  6 char squar[MAXN][MAXN] = { };
  7 int eligible[MAXN][MAXN] = { 0 };
  8 int num[MAXN][MAXN] = { 0 };
  9 int r = 10, c = 10;
 10 int cnt = 0;
 11 
 12 //初始化记录合格白框
 13 //首行,首列置1
 14 void initEligible() {
 15     memset(eligible, 0, sizeof(eligible));
 16     for (int i = 0; i < r; i++) {
 17         eligible[i][0] = 1;
 18     }
 19     for (int j = 0; j < c; j++) {
 20         eligible[0][j] = 1;
 21     }
 22 }
 23 
 24 //输入方阵并记录合格的白框
 25 void scanSquare() {
 26     getchar();
 27     memset(squar, 0, sizeof(squar));
 28     initEligible();
 29     for (int i = 0; i < r; i++) {
 30         for (int j = 0; j < c; j++) {
 31             squar[i][j] = getchar();
 32             //scanf("%c", &squar[i][j]);
 33             if (squar[i][j] == '*') {
 34                 eligible[i][j] = 0;
 35                 eligible[i + 1][j] = 1;
 36                 eligible[i][j + 1] = 1;
 37             }
 38         }
 39         getchar();
 40     }
 41 }
 42 
 43 void getNum() {
 44     memset(num, 0, sizeof(num));
 45     int cnt = 0;
 46     for (int i = 0; i < r; i++) {
 47         for (int j = 0; j < c; j++) {
 48             if (eligible[i][j]) {
 49                 num[i][j] = ++cnt;
 50             }
 51         }
 52     }
 53 }
 54 
 55 //flag为真,表示Across
 56 //flag为假,表示Down
 57 void printPart(bool flag) {
 58 
 59     int tnum[MAXN][MAXN] = { 0 };
 60     memcpy(tnum, num, sizeof(num));
 61     if (flag) {
 62         printf("Across\n");
 63     }
 64     else {
 65         printf("Down\n");
 66     }
 67     for (int i = 0; i < r; i++) {
 68         for (int j = 0; j < c; j++) {
 69             if (tnum[i][j]) {
 70                 int t = i;
 71                 printf("%3d.", tnum[t][j]);
 72                 if (flag) {
 73                     while (squar[i][j] != '*' && j < c) {
 74                         putchar(squar[i][j++]);
 75                     }
 76                 }
 77                 else {
 78                     while (squar[t][j] != '*' && t < r) {
 79                         tnum[t][j] = 0;
 80                         //char ch = flag ? squar[i][t++] : squar[t++][j];
 81                         putchar(squar[t++][j]);
 82                     }
 83                 }
 84                 putchar('\n');
 85             }
 86         }
 87     }
 88 }
 89 
 90 void printSquare() {
 91     //printAcross();
 92     if (cnt) {
 93         putchar('\n');
 94     }
 95     printf("puzzle #%d:\n", ++cnt);
 96     printPart(true);    //Across
 97     printPart(false);    //Down
 98 }
 99 
100 int main() {
101     while (scanf("%d",&r) == 1 && r ) {
102         scanf("%d", &c);
103         scanSquare();
104         getNum();
105         printSquare();
106     }
107     return 0;
108 }