POJ 3348 Cows | 凸包——童年的回忆(误)

本文提供了一种解决POJ3348凸包问题的有效算法实现,利用Graham扫描法找到平面上点集的凸包,并通过C++代码详细展示了整个过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

想当年……还是邱神给我讲的凸包来着……

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define eps 0.000000001
#define enter putchar('\n')
#define space putchar(' ')
using namespace std;
typedef long long ll;
template <class T>
void read(T &x){
    char c;
    bool op = 0;
    while(c = getchar(), c < '0' || c > '9')
    if(c == '-') op = 1;
    x = c - '0';
    while(c = getchar(), c >= '0' && c <= '9')
    x = x * 10 + c - '0';
    if(op) x = -x;
}
template <class T>
void write(T x){
    if(x < 0) putchar('-'), x = -x;
    if(x >= 10) write(x / 10);
    putchar('0' + x % 10);
}
const int N = 10005, INF = 0x3f3f3f3f;
int n, top, ans;
struct point {
    int x, y;
    point(){}
    point(int _x, int _y): x(_x), y(_y){}
    point operator - (point b) const{
    return point(x - b.x, y - b.y);
    }
    int operator * (point b){
    return x * b.y - y * b.x;
    }
    int norm(){
    return x * x + y * y;
    }
} p[N], stk[N], root;
bool operator < (const point &a, const point &b){
    int det = (a - root) * (b - root);
    if(det) return det > 0;
    return (a - root).norm() < (b - root).norm();
}
void graham(){
    int pos = 0;
    root.x = root.y = INF;
    for(int i = 1; i <= n; i++)
    if(p[i].x < root.x || (p[i].x == root.x && p[i].y < root.y))
        root = p[i], pos = i;
    if(pos != 1) swap(p[pos], p[1]);
    sort(p + 2, p + n + 1);
    stk[top = 1] = root;
    for(int i = 2; i <= n; i++){
    while(top >= 2 && (stk[top] - stk[top - 1]) * (p[i] - stk[top - 1]) < 0) top--;
    stk[++top] = p[i];
    }
}
void getarea(){
    stk[top + 1] = stk[1];
    for(int i = 1; i <= top; i++)
    ans += stk[i] * stk[i + 1];
}
int main(){
    read(n);
    for(int i = 1; i <= n; i++)
    read(p[i].x), read(p[i].y);
    graham();
    getarea();
    write(ans / 2 / 50), enter;
    return 0;
}

转载于:https://www.cnblogs.com/RabbitHu/p/POJ3348.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值