uva10078The Art Gallery

题意:判断美术馆是否有关键点,美术馆是一些点,这些点构成的最小边长的边界就是美术馆的边界,看看在这个边界中是否包含一些点,即有些点不在边界上,而在边界内部

解题:求出凸包,看凸包上的点个数是否等于美术馆所有点的个数,相等,没有关键点,小于,包含关键点。

代码:

//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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值