题目大意:至少添加多少着火点才能困住鸡
思路解析:
题目最终被分为两类情况,一类情况就是在鸡的周围添加三个着火点,另一类情况是在鸡周围添加
四个着火点
火 | 火 | 鸡 | 火 | 火 | ||
(火) | 火 | (火) | 火 | (火) | 火 | (火) |
注意添加四个着火点时应使得上下火的曼哈顿距离为1或2
建议使用set<pair<int,int>>v 容器来储存火的坐标,因为可以通过调用类方法count快速判断曼哈顿距离为1或2的火是否存在
废话不多说,代码如下:
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using T = pair<int, int>;
//set<int>S;
//unordered_map<int, int>mp;
const int N = 2e5 + 10;
int a[N];//另一种情况存鸡周围是否有着火点
int main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int t; cin >> t;
while (t--) {
int n; cin >> n;
int i;
for (i = 1; i <= 3; ++i)a[i] = 0;//初始化
set<T>v;//储存着火点的坐标
int l = 2, r = 2;//初始化假设左右两边另需俩着火点
for (i = 1; i <= n; ++i) {
int x, y;
cin >> x >> y;
v.insert({ x,y });
if (y >= 0)r = 1;
if (y <= 0)l = 1;
if (x == 1 && y == -1)a[1] = 1;
if (x == 2 && y == 0)a[2] = 1;
if (x == 1 && y == 1)a[3] = 1;
}
for (auto val : v) {//枚举着火点
int x = val.first;
int y = val.second;
if (x == 1) {
if (v.count({ 2,y - 1 }) || v.count({ 2,y }) || v.count({ 2,y + 1 })) {
if (y < 0)l = 0;
if (y > 0)r = 0;
}
}
else {
if (v.count({ 1,y - 1 }) || v.count({ 1,y }) || v.count({ 1,y + 1 })) {
if (y < 0)l = 0;
if (y > 0)r = 0;
}
}
}
int ans = min(3 - (a[1] + a[2] + a[3]), l + r);
cout << ans << endl;
}
return 0;
}