分析
n <= 1000,l <= 1e9, s <= 50.
直接用数组存整个地图不行(1e9)。因为藏宝图左下角一定是树,所以可以遍历 n 棵树。
思路
遍历 n 棵树,判断当前这棵树作为左下角时是否符合。
假设当前遍历到第 i 棵树,坐标为 sx, sy,则构造其对应的 (S+1, S+1) 矩阵,和藏宝图对应检查。
代码
#include <iostream>
#include <utility>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 1010, M = 55;
int n, l, s;
int b[M][M];
pair<int, int> tree[N];
bool judge(int sx, int sy, int k)
{
if(sx+s > l || sy+s > l) return false;
// 构造矩阵
int c[M][M];
memset(c, 0, sizeof c);
for(int i = k; i < n; i++)
{
int x = tree[i].first;
int y = tree[i].second;
x = x-sx;
y = y-sy;
if(x < 0 || x > s) continue;
if(y < 0 || y > s) continue;
c[x][y] = 1;
}
for(int i = 0; i <= s; i++)
for(int j = 0; j <= s; j++)
{
if(b[i][j] != c[i][j])
return false;
}
return true;
}
int main()
{
cin >> n >> l >> s;
for(int i = 0; i < n; i++)
cin >> tree[i].first >> tree[i].second;
for(int i = 0; i <= s; i++)
for(int j = 0; j <= s; j++)
cin >> b[s-i][j];
sort(tree, tree+n);
int num = 0;
for(int i = 0; i < n; i++)
{
int sx = tree[i].first;
int sy = tree[i].second;
if(judge(sx, sy, i)) num++;
}
cout << num;
return 0;
}
反思
这个题这么简单,但是调试了好久。
- 要熟悉在 csp 官网上提交调试,没有数据反馈所以更要对代码逻辑清晰。
- 因为题目很简单,所以一开始官网上显示 0 分的时候我以为是 dev 没报编译出错,但官网上编译情况不同造成的。-> 官网上既然写了是错误而非编译错误就要找代码逻辑问题,dev 和 官网的环境相同,不需要自己杞人忧天。
- 在根据左下角树构造其对应的矩阵时,自己把判断条件想得太细了,不应该这样,比赛时只要够用就行,找到一个满足要求的充分条件的写法就好,怎么简单怎么写。