纵横字谜的答案(Crossword Answer,ACM/ICPC Word Finals 1994,UVa232)

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

纵横字谜的答案(Crossword Answer,ACM/ICPC Word Finals 1994,UVa232)_第1张图片

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

原题链接为:http://vjudge.net/problem/32396;jsessionid=77F851C8173BEEC794C27506A9B99AA8



本题可利用两个数组来进行网格模拟和标记,通过多重循环来进行输出和标记,特别要注意第一个字符为‘*’和重复出现‘*’的情况,每次

#include
#define maxn 100
char word[maxn][maxn] = { '\0' };//定义输入网格和标记网格
int mark[maxn][maxn];

int main()
{
	int r, c;
	scanf("%d%d", &r, &c);
	for (int i = 0; i < r; i++) {
		getchar();
		for (int j = 0; j < c; j++)
			scanf("%c", &word[i][j]);
	}
	for (int i = 0; i < r; i++)//对网格进行标记
		for (int j = 0; j < c; j++) {
			if (word[i][j] != '*')
				if (word[i - 1][j] == '*' || word[i][j - 1] == '*' || i - 1 < 0 || j - 1 < 0)
					mark[i][j] = 2;
				else
					mark[i][j] = -1;
			else
				mark[i][j] = -1;
		}
	//输出横向,每个输出过的字母标记为1
	printf("\nAcross:\n");
	for (int i = 0; i < r; i++) {
		for (int j = 0; word[i][j]!='\0'; j++) {
			if (word[i][j] != '*'&&mark[i][j] != 1) {
				printf("%c", word[i][j]);
				mark[i][j] = 1;
			}
			//判断语句,处理第一个字符为‘*’和出现多个‘*’的情况
			if(word[i][j]=='*'&&word[i][j-1]!='*'&&word[i][j+1]!='*'&&word[i][j+1]!='\0'&&word[i][j-1]!='\0'&&mark[i][j]!=1)
				printf("\n");
		}
		printf("\n");
	}
	//输出竖向,每个输出过的字母标记为0
	printf("\nDown:\n");
	for (int j = 0; j < c; j++) {
		for (int i = 0; word[i][j] != '\0'; i++) {
			if (word[i][j] != '*'&&mark[i][j] != 0) {
			printf("%c", word[i][j]);
			mark[i][j] = 0;
		}
			//判断语句,处理第一个字符为‘*’和出现多个‘*’的情况
			if(word[i][j] == '*'&&word[i-1][j]!='*'&&word[i+1][j]!='*'&&word[i+1][j] != '\0'&&word[i-1][j] != '\0'&&mark[i][j] != 0)
				printf("\n"); 
		}
		printf("\n");
	}
	return 0;
}



你可能感兴趣的:(纵横字谜的答案(Crossword Answer,ACM/ICPC Word Finals 1994,UVa232))