CCF認證 201912-02 回收站選址 (100分)
// INFO BEGIN
// Group = C/C++
// Problem = 回收站選址
// Language = CPP11
// SubmitTime = 2019-12-15 15:04:48
//
// INFO END
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=1e3+100;
typedef long long ll;
struct point{
ll x,y;
Point(){}
Point(ll _x,ll _y){
x=_y;y=_y;
}
}P[maxn],C[maxn];
bool cmp1(point a,point b){
if(a.x!=b.x) return a.x<b.x;
return a.y<b.y;
}
bool cmp2(point a,point b){
if(a.y!=b.y) return a.y<b.y;
return a.x<b.x;
}
int find(point t,int n){//C[] y sort
int l=0,r=n;
while(l<=r){
int mid=(l+r)/2;
if(C[mid].y<t.y) l=mid+1;
else r=mid-1;
}//與y相等的最左邊的
int L=l; l=0,r=n;
while(l<r){
int mid=(l+r)/2;
if(C[mid].y<=t.y) l=mid+1;
else r=mid-1;
}//與y相等的最右邊
int R=r;//y相同的範圍內找x
//cout<<"LR:"<<L<<" "<<R<<endl;
while(L<=R){
int mid=(L+R)/2;
if(C[mid].x==t.x&&C[mid].y==t.y) return mid;
if(C[mid].x<=t.x) L=mid+1;
else R=mid-1;
}
return R;
}
int main(){
int n;
cin>>n;
int ans[5];
for(int i=0;i<5;i++) ans[i]=0;
for(int i=0;i<n;i++) cin>>P[i].x>>P[i].y,C[i]=P[i];
sort(P,P+n,cmp1);
sort(C,C+n,cmp2);
// for(int i=0;i<n;i++) cout<<i<<"P:"<<P[i].x<<" "<<P[i].y<<endl;
// for(int i=0;i<n;i++) cout<<i<<"C:"<<C[i].x<<" "<<C[i].y<<endl;
for(int i=1;i<n-1;i++){
if(P[i].y+1!=P[i+1].y) continue;
if(P[i].y-1!=P[i-1].y) continue;//上下有了
//找到P[i] 對應C[i]的id
int index=find(P[i],n);
if(index+1<n&&C[index].x+1!=C[index+1].x) continue;
if(index-1>=0&&C[index].x-1!=C[index-1].x) continue;//左右有了
// cout<<"P:"<<P[i].x<<" "<<P[i].y<<endl;
// cout<<index<<":"<<C[index].x<<" "<<C[index].y<<endl;
//滿足條件 計算個數
int tmp=0;
index=find(P[i+1],n);
// cout<<index<<" ";
if(index+1<n&&C[index].x+1==C[index+1].x) tmp++;
if(index-1>=0&&C[index].x-1==C[index-1].x) tmp++;//左右有了
index=find(P[i-1],n);
// cout<<index<<" ";
if(index+1<n&&C[index].x+1==C[index+1].x) tmp++;
if(index-1>=0&&C[index].x-1==C[index-1].x) tmp++;//左右有了
// cout<<tmp<<" "<<endl;
ans[tmp]++;
}
for(int i=0;i<5;i++) cout<<ans[i]<<endl;
return 0;
}