枚举每个横向和纵向长度为 K 的连续区间,判断其中是否全部为空地;K=1 时单独计数空格。
OJ: luogu
题目 ID: P3654
难度:入门
标签:枚举矩阵python
日期: 2026-07-15 21:40
题意
给定一个 R x C 的矩阵,. 表示空地,# 表示障碍。要找出有多少种方法放下一条长度为 K 的直线队伍,方向可以横向或纵向,所有位置都必须是空地。
思路
直接枚举每个可能的起点。
横向放置时,起点 (row, col) 需要满足 col + K - 1 < C,然后检查这一段是否全是 .。
纵向放置时,起点 (row, col) 需要满足 row + K - 1 < R,然后检查这一段是否全是 .。
需要特别注意 K = 1。此时横向和纵向的同一个空格表示同一种站位,不能重复计数,所以直接统计空地数量。
Python 知识
all(...)可以判断一段格子是否全部满足条件,并且遇到第一个不满足的格子会短路。row.count(".")可以统计一行中的空地数量。- 用
range(c - k + 1)控制横向起点,避免越界。
参考笔记:
/home/rainboy/mycode/hugo-blog/content/program_language/python/generator_expression.md/home/rainboy/mycode/hugo-blog/content/program_language/python/input_output_and_strings.md
代码
python
r, c, k = map(int, input().split())
grid = [input().strip() for _ in range(r)]
if k == 1:
print(sum(row.count(".") for row in grid))
else:
answer = 0
for row in range(r):
for col in range(c - k + 1):
if all(grid[row][col + offset] == "." for offset in range(k)):
answer += 1
for row in range(r - k + 1):
for col in range(c):
if all(grid[row + offset][col] == "." for offset in range(k)):
answer += 1
print(answer)cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-07-27 00:00
* update_at: 2026-07-27 00:00
*/
#include <bits/stdc++.h>
using namespace std;
int r, c, k;
char grid[105][105];
int main() {
cin >> r >> c >> k;
for (int i = 0; i < r; i++) cin >> grid[i];
if (k == 1) {
int ans = 0;
for (int i = 0; i < r; i++)
for (int j = 0; j < c; j++)
if (grid[i][j] == '.') ans++;
cout << ans << endl;
return 0;
}
int ans = 0;
for (int i = 0; i < r; i++) {
for (int j = 0; j <= c - k; j++) {
bool ok = true;
for (int t = 0; t < k; t++)
if (grid[i][j + t] != '.') { ok = false; break; }
if (ok) ans++;
}
}
for (int i = 0; i <= r - k; i++) {
for (int j = 0; j < c; j++) {
bool ok = true;
for (int t = 0; t < k; t++)
if (grid[i + t][j] != '.') { ok = false; break; }
if (ok) ans++;
}
}
cout << ans << endl;
return 0;
}复杂度
每个起点最多检查 K 个格子,时间复杂度为
总结
矩阵枚举题先确定“起点范围”,再写合法性检查。K=1 的重复计数是本题最容易漏掉的边界。
