n = s.size(); for(int i = 0, len = n; i < n; i ++, len --) { string t = s.substr(i, len); if(check(t)) { string prev = s.substr(0, i); string post = prev; if(prev.size()) { reverse(post.begin(), post.end()); cout << prev + t + post << endl; return 0; } else { cout << t << endl; return 0; } } }
return 0; } ``` ## I题 ### 题面
给定一个字母矩阵。一个 X 图形由中心点和由中心点向四个45度斜线方向引出的直线段组成,四条线段的长度相同,而且四条线段上的字母和中心点的字母相同。 一个 X图形可以使用三个整数 r, c, L 来描述,其中 r, c 表示中心点位于第 r 行第 c 列,正整数 L 表示引出的直线段的长度。 对于 1 到 L 之间的每个整数 i,X图形满足:第 r-i 行第 c-i 列与第 r 行第 c 列相同,第 r-i 行第 c+i 列与第 r 行第 c 列相同,第 r+i 行第 c-i 列与第 r 行第 c 列相同,第 r+i 行第 c+i 列与第 r 行第 c 列相同。 例如,对于下面的字母矩阵中,所有的字母 L 组成一个 X图形,其中中间的 5 个 L 也组成一个 X图形。所有字母 Q 组成了一个 X图形。 LAAALA ALQLQA AALQAA ALQLQA LAAALA 给定一个字母矩阵,请求其中有多少个 X图形。 ### 输入格式 输入第一行包含两个整数 n, m,分别表示字母矩阵的行数和列数。 接下来 n 行,每行 m 个大写字母,为给定的矩阵。 ### 输出格式 输出一行,包含一个整数,表示答案。 ### 数据范围 对于 50% 的评测用例,1 <= n, m <= 10。 对于所有评测用例,1 <= n, m <= 100。 ### 算法(枚举) 由于本题的数据量较小,暴力枚举即可,细节见代码。
inline bool isInner(int x, int y) { return x >= 1 && x <= n && y >= 1 && y <= m; }
inline bool check(char c, int x, int y, int d) { int ax = x - d, ay = y - d; int bx = x - d, by = y + d; int cx = x + d, cy = y - d; int dx = x + d, dy = y + d; if(isInner(ax, ay) && isInner(bx, by) && isInner(cx, cy) && isInner(dx, dy)) { return c == g[ax][ay] && g[ax][ay] == g[bx][by] && g[bx][by] == g[cx][cy] && g[cx][cy] == g[dx][dy]; } return false; }
inline int get(int x, int y) { char c = g[x][y]; int d = 1; while(check(c, x, y, d)) d ++; return d - 1; }
int main() { scanf("%d%d", &n, &m); for(int i = 1; i <= n; i ++) scanf("%s", g[i] + 1);
int res = 0; for(int i = 2; i < n; i ++) for(int j = 2; j < m; j ++) res += get(i, j);