1 条题解
-
0
1952E - 扫线 详细题解(官方标程版)
题意规范化翻译
有一个一维扫雷游戏,只有一行格子。 给定长度为 的数组 ,满足 。 每个 表示第 格左右相邻格子的地雷总数(不含自身)。
设 表示第 格是否有地雷:
- :有地雷
- :没有地雷
则对每个 必须满足:
边界约定: (最左、最右外都没有地雷)。
求合法地雷布局 的方案数,答案对 取模。 (标程指出:答案只会是 ,取模无实际意义。)
核心结论(标程原话)
整个数组 由 唯一确定。 只有 或 两种可能,因此总方案数 。
严格推导(标程逻辑)
由约束:
移项得到递推式:
第一步:由 直接得
时:
所以:
第二步:递推推出全部
对 :
每一步必须满足:
否则该 对应的方案非法。
第三步:最终校验(关键)
时:
所以必须满足:
不满足则方案非法。
算法流程(标准 )
- 枚举
- 对每个 :
- 令
- 若 ,非法
- 递推 :
- 若任意 ,非法
- 最后检查
- 统计合法的 数量即为答案。
特殊情况:
此时:
只有 时有 种方案,否则 。
标程风格可AC代码(极简、无冗余)
#include <iostream> #include <vector> using namespace std; const int MOD = 20240401; int test(int n, vector<int>& a, int x1) { vector<int> x(n + 2, 0); x[1] = x1; x[2] = a[1]; if (x[2] < 0 || x[2] > 1) return 0; for (int i = 2; i <= n - 1; ++i) { x[i+1] = a[i] - x[i-1]; if (x[i+1] < 0 || x[i+1] > 1) return 0; } return (a[n] == x[n-1]) ? 1 : 0; } int main() { ios::sync_with_stdio(false); cin.tie(0); int n; cin >> n; vector<int> a(n+1); for (int i=1; i<=n; ++i) cin >> a[i]; if (n == 1) { cout << (a[1] == 0) << endl; return 0; } int ans = test(n,a,0) + test(n,a,1); cout << ans % MOD << endl; }
复杂度
- 时间:
- 空间:(可优化到 ,标程常用)
答案为什么最多是 2?
因为只有两个可能:
每个唯一确定整个布局,最多两个合法。
- 1
信息
- ID
- 6525
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者