原题地址
解题思路
(想的有点麻烦)
读入一个表之后要进行三次遍历:
第一次进行标记,把是某个横字符串或者竖字符串的第一个字符打上标记。
第二次将标记变成标号(注意题目要求),同时把每行的横字符串都输出。
第三次把每列的竖字符串都输出。
注意事项
1.注意输出竖字符串的顺序。要按照标号的顺序进行遍历输出。
解题总结
1.找连续字符的时候用while
比较好写~
参考代码
#include<bits/stdc++.h>
using namespace std;
#define LOCAL //提交的时候一定注释
#define _for(i, a, b) for(int i = (a); i < (b); ++i)
#define _rep(i, a, b) for(int i = (a); i <= (b); ++i)
#define pb push_back
#define VI vector<int>
#define maxn 15
#define INF 0x3f3f3f3f
typedef long long LL;
vector<string> t;
int label[maxn][maxn];
int readint() {
int x; scanf("%d", &x); return x;
}
void l(int n, int m) {
//遍历横行
_for(i, 0, n) {
_for(j, 0, m) {
bool flag = false;
if (i == 0 && t[i][j] != '*') flag = true;
else if (j == 0 && t[i][j] != '*') flag = true;
else if (i > 0 && t[i - 1][j] == '*' && t[i][j] != '*') flag = true;
else if (j > 0 && t[i][j - 1] == '*' && t[i][j] != '*') flag = true;
if (flag) label[i][j] = 1;
}
}
printf("Across\n");
int cnt = 0, fst;
string s;
_for(i, 0, n) {
s = "";
_for(j, 0, m) {
if (label[i][j]) {
label[i][j] = ++cnt; //首先打一下标号
}
if (t[i][j] != '*') {
if (s == "") {
fst = label[i][j];
}
s += t[i][j];
}
if (t[i][j] == '*' || j == m - 1){ //这里是逐个处理的,所以没有写while循环~
if (s != "") {
printf("%3d.%s\n", fst, s.c_str());
s = "";
}
}
}
}
printf("Down\n");
s = "";
_for(i, 0, n) {
_for(j, 0, m) {
if (t[i][j] != '*' && label[i][j]) {
fst = label[i][j];
int x = i, y = j;
while (x < n && t[x][y] != '*') { //这里比较好写
s += t[x++][y];
label[x][y] = 0; //访问过的进行标记
}
printf("%3d.%s\n", fst, s.c_str());
s = "";
}
}
}
}
int main() {
#ifdef LOCAL
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
string s;
int n, m, cnt = 0;
while (~scanf("%d%d", &n, &m) && n) {
getchar();
if (cnt) printf("\n");
printf("puzzle #%d:\n", ++cnt);
t.clear();
memset(label, 0, sizeof(label));
_for(i, 0, n) {
getline(cin, s);
t.pb(s);
}
l(n, m);
}
return 0;
}