poj 2007 Scrambled Polygon

题意:给你一个封闭的凸多边形上的顶点,按逆时针方向输出顶点。


分析:该开始以为是求凸包,后来发现题目给你的就是凸包,只是点的顺序打乱了,用叉积排序后,输出即可。


以下附上代码:

#include <algorithm>
#include <iostream>
#include <sstream>
#include <fstream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cctype>
#include <cmath>
#include <stack>
#include <queue>
#include <list>
#include <map>
#include <set>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;

struct Point{
  double x,y;
  
  Point(){}
  Point(double x_, double y_) :
    x(x_), y(y_) {}
  
  
  Point operator - (const Point &b) const{
    Point t(x-b.x,y-b.y);
    return t;
  }
  
  double operator ^ (const Point &b) const{
    return x*b.y - y*b.x;
  }
  
  bool operator < (const Point &b) const{
    Point c(0,0);
    Point va = *this - c;
    Point vb = b - c;
    return (va ^ vb) > 0;
  }
  
};

const int maxn = 100005;

Point a[maxn];

int main()
{
  int x,y;
  int cnt = 0;
  while(scanf("%lf%lf",&a[cnt].x,&a[cnt].y) != EOF) ++cnt;
  sort(a+1,a+cnt);
  for(int i = 0; i < cnt; i++){
    printf("(%.0lf,%.0lf)\n",a[i].x,a[i].y);
  }
	return 0;
}


Graham 算法:

#include <algorithm>
#include <iostream>
#include <sstream>
#include <fstream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cctype>
#include <cmath>
#include <stack>
#include <queue>
#include <list>
#include <map>
#include <set>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;

const int maxn = 100005;

struct Point{
  int x,y;
  
  Point(){}
  Point(int x_, int y_) :
    x(x_), y(y_) {}
  
  bool operator < (const Point &b) const{
    if(x != b.x) return x < b.x;
    return y < b.y;
  }
  
  Point operator - (const Point &b) const{
    Point t(x-b.x,y-b.y);
    return t;
  }
  
  
  //vector
  int operator * (const Point &b) const{
    return x*b.x + y*b.y;
  }
  
  int operator ^ (const Point &b) const{
    return x*b.y - y*b.x;
  }
  
  int len2(){
    return x*x+y*y;
  }
};


Point a[maxn];
int n;
int res[maxn];
int cnt;



bool cmp(Point ta, Point tb)
{
  Point v1 = ta - a[0];
  Point v2 = tb - a[0];
  
  if((v1 ^ v2) != 0) return (v1 ^ v2) > 0;
  else return v1.len2() < v2.len2();
}

void Graham()
{
  cnt = 0;
  if(n == 0) return; res[cnt++] = 0;
  if(n == 1) return; res[cnt++] = 1;
  if(n == 2) return; 
  
  Point v1,v2;//vector
  
  for(int i = 2; i < n; i++){
    while(cnt){
      v1 = p[res[cnt-1]] - p[res[cnt-2]];
      v2 = p[i] - p[res[cnt-1]];
      if((v1 ^ v2) >= 0) break;
      --cnt;
    }
    
    res[cnt++] = i;
  }
  
}

int main()
{
  n = 0;
  while(scanf("%d%d",&a[n].x,&a[n].y) != EOF) ++n;
  sort(a+1,a+n,cmp);
  Graham();
  for(int i = 0; i < cnt; i++){
    printf("(%d,%d)\n",a[res[i]].x,a[res[i]].y);
  }
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值