1 solutions
-
0
由于 过大,因此开二维数组显然不可行,只能获得至多 70 分。
但是树的个数不超过 ,因此可以把树用 Hash 表记录一下。以下给出了一种对
pair<int, int>
重载哈希函数的写法,当然了,自己直接对坐标压缩也是可以的。接下来判断以 个树分别对应到藏宝图左下角 的情况,每种情况是否合法,合法则答案加 1 就行。注意出界的情况需要直接判非法。
如果将哈希表查找时间视为复杂度 的话,则总时间复杂度为 可以通过。
#include <stdio.h> #include <algorithm> #include <unordered_set> // 快速输入输出 void wr(int x) { if (x < 0) putchar('-'), x = -x; if (x > 9) wr(x / 10); putchar((x % 10) ^ '0'); } int rd() { int k = 0, f = 1; char c = getchar(); while (c < '0' || c > '9') { if (c == '-') f = 0; c = getchar(); } while (c >= '0' && c <= '9') { k = (k << 1) + (k << 3) + (c ^ '0'); c = getchar(); } return f ? k : -k; } int n, L, S; std::pair<int, int> a[1010]; struct edge_hash { size_t operator()(const std::pair<int, int>& a) const { return std::hash<int>()(a.first) * 611953 + std::hash<int>()(a.second) * 7919; } }; std::unordered_set<std::pair<int, int>, edge_hash> mp; int B[55][55]; bool judge(int idx) { if (a[idx].first + S > L || a[idx].second + S > L) return 0; // count 代表是否存在(非可重集只会返回 0 或者 1),亦或结果不为 0 等价于两个数不相等 for (int i = 0; i <= S; ++i) for (int j = 0; j <= S; ++j) if (B[i][j] ^ mp.count(std::make_pair(a[idx].first + i, a[idx].second + j))) return 0; return 1; } int main() { n = rd(), L = rd(), S = rd(); for (int i = 1; i <= n; ++i) a[i].first = rd(), a[i].second = rd(), mp.insert(a[i]); for (int i = S; i >= 0; --i) for (int j = 0; j <= S; ++j) B[i][j] = rd(); int ans = 0; for (int i = 1; i <= n; ++i) ans += judge(i); wr(ans); }
Information
- ID
- 33
- Time
- 500ms
- Memory
- 512MiB
- Difficulty
- 1
- Tags
- # Submissions
- 16
- Accepted
- 8
- Uploaded By