题意:判断美术馆是否有关键点,美术馆是一些点,这些点构成的最小边长的边界就是美术馆的边界,看看在这个边界中是否包含一些点,即有些点不在边界上,而在边界内部
解题:求出凸包,看凸包上的点个数是否等于美术馆所有点的个数,相等,没有关键点,小于,包含关键点。
代码:
//uva10078 The Art Gallery
//AC By Warteac
//Runtime:0.013s
//2013-5-14
#include<iostream>
#include<cstdio>
#include<vector>
#include<stack>
#include <iomanip>
#include<algorithm>
#include<cmath>
using namespace std;
typedef int PType;//定义点的类型
///
struct point{
PType x,y;
point(PType a = 0, PType b = 0){x = a; y = b;}
void transfer(point p){x -= p.x, y -= p.y;}
void restore(point p){x += p.x, y += p.y;}
void print(){cout << "x = " << x << "y = " << y << endl;}
};
int direction(point v1,point v2){
return (v1.x*v2.y-v1.y*v2.x);
}
bool cmp(point p1,point p2){
return (p1.x*p2.y < p1.y*p2.x);
}
bool grham_scan(vector <point> p , vector <point> &parray){
//find first point p0 with minimum y-coordinate or minimun x-coordinate if y are the same
PType x = p[0].x, y = p[0].y;
int index = 0,i;
for(i = 1; i < p.size(); i++){
if(p[i].y > y) continue;
if(p[i].y < y){
y = p[i].y; x = p[i].x; index = i;
}else if(p[i].x < x){
y = p[i].y; x = p[i].x; index = i;
}
}
point t = p[index];
p[index] = p[0];
p[0] = t;
//transfer points by p0
for(int j = 0; j < p.size(); j++){
p[j].transfer(t);
}
//let (p1,p2……pm) sorted by polar angle
sort(p.begin()+1,p.end(),cmp);
//delete those points with the same polar angle but the farthest ont from p0
vector <point> ps;//saved in ps
ps.clear();
ps.push_back(p[0]);
ps.push_back(p[1]);
for(int i = 2; i < p.size(); i++){
if(cmp(ps.back(),p[i])){
ps.push_back(p[i]);
}else if(ps.back().x < p[i].x){
ps.back() = p[i];
}
}
if(ps.size() <= 2) return false;
//get the convex hull from ps
parray.clear();
parray.push_back(ps[0]);
parray.push_back(ps[1]);
ps.push_back(ps[0]);
for(int i = 2; i < ps.size(); i++){
point v1 (ps[i].x - parray.back().x, ps[i].y - parray.back().y);
point v2 (parray.back().x - (parray.end()-2)->x, parray.back().y - (parray.end()-2)->y);
int d = direction(v2,v1);
if(d <= 0) {parray.push_back(ps[i]);}
else if(d > 0){
parray.pop_back();i--;
}
}
//restore the points' coordinate
for(int j = 0; j < parray.size(); j++){
parray[j].restore(t);
}
return true;
}
//
int main(){
int sites;
PType x,y;
vector <point> v;
point t,mi;
vector < vector <point> > p;//convex hull
int aflag[105] = {0};
int area = 0;
//input kingdom
while(cin >> sites && sites){
v.clear();
vector <point> temp;//one convex hull
while(sites--){
cin >> t.x >> t.y;
v.push_back(t);
}
//computing convex hull
if(grham_scan(v,temp) == true){
if(temp.size() == v.size()+1)
cout << "No" << endl;
else cout << "Yes" <<endl;
}else{
cout << "no convex hull" << endl;
}
}
return 0;
}