纵横字谜的答案(Crossword Answers)
Posted vincent-yuan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了纵横字谜的答案(Crossword Answers)相关的知识,希望对你有一定的参考价值。
题目
输入一个r行c列(1<=r, c<=10)的网格,黑格用 * 表示,每个白格都填有一个字母。
如果一个白格的左边相邻位置或者上边相邻位置没有白格(可能是黑格,也可能出了网格边界),
则称这个白格是一个起始格。
首先把所有起始格按照从上到下,从左到右的顺序编号为1,2,3,... ,如图
接下来要找出所有横向单词(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
分析
用s[][] 存储r行c列的字符,lable[][]用来标记对应位置起始格的编号;
1.检测起始格
2.检测横向单词和竖向单词
c实现
#include<stdio.h> #include<string.h> #define maxn 12 int main(){ //r行,c列 int r,c; while(scanf("%d",&r)&&r){ scanf("%d",&c); char s[r][c]; //依次输入每行的数据 for(int i=0;i<r;i++) { scanf("%s",s[i]); } //用来标记起始格的序号1,2,... int lable[r][c]; int count=0; //检测标记对应位置的起始格 for(int i=0;i<r;i++){ for(int j=0;j<c;j++) { //起始格:首先不是黑格,然后为边界或者(左边相邻位置或者上边相邻位置没有白格) if(s[i][j]!=‘*‘&&(i==0||j==0||s[i-1][j]==‘*‘||s[i][j-1]==‘*‘)) { lable[i][j] = (++count); }else{ lable[i][j] = 0;//非起始格标记为0 } } } //横向输出 printf("Across "); for(int i=0;i<r;i++) { for(int j=0;j<c;j++) { //横向单词满足的条件:首先该位置是起始格,然后左边界或左边相邻位置为黑格 if(lable[i][j]>0&&(j==0||s[i][j-1]==‘*‘)) { printf("%d.%c",lable[i][j],s[i][j]); for(int k=j+1;k<c;k++){ if(s[i][k]==‘*‘){ break; }else{ printf("%c",s[i][k]); } } printf(" "); } } } printf("Down "); for(int i=0;i<r;i++){ for(int j=0;j<c;j++){ //竖向单词满足的条件:首先该位置是起始格, 然后为上边界或者上边相邻位置为黑格 if(lable[i][j]>0&&(i==0||s[i-1][j]==‘*‘)) { printf("%d.%c",lable[i][j],s[i][j]); for(int k=i+1;k<r;k++){ if(s[k][j]==‘*‘){ break; }else{ printf("%c",s[k][j]); } } printf(" "); } } } } return 0; }
以上是关于纵横字谜的答案(Crossword Answers)的主要内容,如果未能解决你的问题,请参考以下文章
[算法竞赛入门经典] Crossword Answers ACM/ICPC World Finals 1994,UVa232