https://ac.nowcoder.com/acm/contest/67741/B
本题使用set<pair<int,int>>st来存放数据可以做到高效查找
考虑以下两种情况
情况一、火鸡左右分别被包围最多4堆火
或者上下两堆火间距不超过1
情况二、火鸡左右下被包住,最多3堆火
还有一种特殊情况,一侧被包围,加上(2,0)位置有火,这种情况特殊考虑,仅需加入一堆火即可,ans=min(1,ans)
各种情况的代码实现看以下注释
#include<iostream>
#include<set>
using namespace std;
void solve(){
int n;cin>>n;
set<pair<int,int>>st;
//情况一,共有4堆火
int l=2,r=2;
for(int i=1;i<=n;i++){
int x,y;cin>>x>>y;
st.insert({x,y});
if(y<0) l=1;
if(y>0) r=1;
}
for(auto x:st){
if(x.first==1){
if(x.second<0){
if(st.count({2,x.second})) l=0;
if(st.count({2,x.second-1})) l=0;
if(st.count({2,x.second+1})) l=0;
}else if(x.second>0){
if(st.count({2,x.second})) r=0;
if(st.count({2,x.second-1})) r=0;
if(st.count({2,x.second+1})) r=0;
}
}else{
if(x.second<0){
if(st.count({1,x.second})) l=0;
if(st.count({1,x.second-1})) l=0;
if(st.count({1,x.second+1})) l=0;
}else if(x.second>0){
if(st.count({1,x.second})) r=0;
if(st.count({1,x.second-1})) r=0;
if(st.count({1,x.second+1})) r=0;
}
}
}
int ans1=l+r;
/***********************************************/
//情况2,最多3堆火
int ans2=3;
if(st.count({2,0})) {
//特殊情况***
ans2--;
if(l==0||r==0) ans1=min(ans1,1);
}/*********/
if(st.count({1,-1})) ans2--;
if(st.count({1,1})) ans2--;
/***********************************************/
//输出两种情况的最小值即可
cout<<min(ans1,ans2)<<endl;
}
int main(){
int T;cin>>T;
while(T--){
solve();
}
}