符合 FJ的要求有兩種情況:三條直線平行或者兩條直線平行並與一條直線垂直.至於橫豎的問題,可以通過反轉奶牛的座標轉化成相同的方式.
三條平行直線:
把所有點的橫座標記錄下來,如果不同的橫座標個數小於等於3,那麼符合條件.
兩條平行與一條直線垂直:把所有的縱座標和它們個數記下,也記下所有出現的縱座標個數,再按照橫座標排序,再枚舉一個橫座標a,表示這條直線x=a與其他兩條橫線垂直,再把這條直線上的所有縱座標cnt--,再看縱座標出現的個數,如果<=2,說明成立.
標程寫的比我的精煉很多,那我就放標程吧…
#include <cstdio>
#include <cstring>
#include <map>
#include <algorithm>
using namespace std;
const int MAXN = 1001000;
pair<int,int> lis[MAXN];
map<int, int> cou;
int distinct;
int n;
void inc(int x) {
if(cou[x] == 0) {
distinct++;//不同縱座標的個數
}
cou[x] = cou[x] + 1;
}
void dec(int x) {
cou[x] = cou[x] - 1;
if(cou[x] == 0) distinct--;
}
int moo() {
sort(lis, lis + n);//排序,把相同橫座標的放在一起
distinct = 0;
cou.clear();
for(int i = 0; i < n; ++i) {
inc(lis[i].second);
}
if(distinct <= 3) return 1;//三條平行
int i = 0, i1 = 0;
while(i < n) {
while(i1 < n && lis[i].first == lis[i1].first) i1++;
for(int i2 = i; i2 < i1; ++i2) dec(lis[i2].second);//刪除一條豎線上的所有縱座標
if(distinct <= 2) return 1;
for(int i2 = i; i2 < i1; ++i2) inc(lis[i2].second);
i = i1;
}
return 0;
}
int main() {
scanf("%d", &n);
for(int i = 0; i < n; ++i)
scanf("%d%d", &lis[i].first, &lis[i].second);
if(moo()) {
puts("1");
}
else {
for(int i = 0; i < n; ++i) {
swap(lis[i].first, lis[i].second);//把座標反轉
}
if(moo()) puts("1");
else puts("0");
}
return 0;
}