UVa 232, Crossword Answers
2016-02-26 19:56
309 查看
Problem
传送门Mean1
输入一个r行c列(1≤r, c≤10)的网格,黑格用“*”表示,每个白格都填有一个字母。如果一个白格的左边相邻位置或者上边相邻位置没有白格(可能是黑格,也可能出了网格边界),则称这个白格是一个起始格。首先把所有起始格按照从上到下、从左到右的顺序编号为1,2,3,…。
接下来要找出所有横向单词(Across)。这些单词必须从一个起始格开始,向右延伸到一个黑格的左边或者整个网格的最右列。最后找出所有竖向单词(Down)。这些单词必须从一个起始格开始,向下延伸到一个黑格的上边或者整个网格的最下行。
Analysis
首先搜索起始格并依次打标记。以数组a,b记录横纵坐标信息,数组u,w记录横向起始格序列与纵向起始格序列。处理横向单词时依次访问u数组记录未访问过的点(其横纵坐标已由a,b数组记录),并把已访问过的点标记以避免重复访问。
纵向单词亦然。由于此前为避免重复访问已对u数组进行过修改,所以特意使用w数组。
Code
#include<stdio.h> #include<cstring> char map[15][15]; int a[105],b[105],u[15][15],w[15][15]; int r,c,cnt,t=0; void de(int x,int y){ if(map[x][y]!='*' && (x==0 || y==0 || map[x-1][y]=='*' || map[x][y-1]=='*')){ u[a[++cnt]=x][y]=1;w[x][b[cnt]=y]=1; } } int main(){ while(~scanf("%d",&r) && r){ memset(map,0,sizeof(map)); if(t) printf("\n"); scanf("%d",&c); for(int i=0;i<r;i++) scanf("%s",map[i]); cnt=0; for(int i=0;i<r;i++) for(int j=0;j<c;j++) de(i,j); printf("puzzle #%d:\nAcross\n",++t); for(int i=1;i<=cnt;i++) if(u[a[i]][b[i]]){ int x=a[i],y=b[i]; printf("%3d.",i); for(;;){ u[x][y]=0; putchar(map[x][y]); if(++y>=c || map[x][y]=='*'){printf("\n");break;} } } printf("Down\n"); for(int i=1;i<=cnt;i++) if(w[a[i]][b[i]]){ int x=a[i],y=b[i]; printf("%3d.",i); for(;;){ w[x][y]=0; putchar(map[x][y]); if(++x>=r || map[x][y]=='*'){printf("\n");break;} } } } return 0; }
来自刘汝佳《算法竞赛入门经典(第2版)》 ↩
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++高级程序员成长之路
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C与C++之间相互调用实例方法讲解
- 解析C++中派生的概念以及派生类成员的访问属性