几道凸包题

poj1113 Wall
题意: 略。
思路:求凸包。

AC代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <map>
#include <cmath>
#include <string>
#include <stack>
#include <queue>
#include <vector>
#include <set>
const int  mod = 1e9+7;
#define ll long long
#define llu unsigned long long
using namespace std;
map<string,int>mp;
const int maxn = 100550+10;
const double eps = 0.0000001;
const double PI = 3.1415926;
int v[maxn],a[maxn];

struct Point {
    double x,y;
    Point(double x=0,double y=0):x(x),y(y){}
};
int n;
Point p[1150],s[1150];  //一开始数组开小了,wa了好几次。

double cross(Point a,Point b,Point c) {
    return ((b.x-a.x)*(c.y-a.y) - (b.y-a.y)*(c.x-a.x));
}
double dis(Point a,Point b) {
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));

}

bool cmp(Point a,Point b) {
    if(a.x != b.x) return a.x<b.x;
    else return a.y<b.y;
}

bool cmp1(Point a,Point b) {
    double m = cross(p[0],a,b);
    if(fabs(m-0.0) <= eps) {
        if(dis(p[0],b) > dis(p[0],a)) return true;
        else return false;
    }
    else {
        if(m>0) return true;
        else return false;
    }
}

int main(){
//        freopen("1.in","r",stdin);
    double l;
    while(scanf("%d%lf",&n,&l)!=EOF){
        for(int i=0;i<n;i++) {
            scanf("%lf%lf",&p[i].x,&p[i].y);
        }
        sort(p,p+n,cmp);
        sort(p+1,p+n,cmp1);
        s[0].x = p[0].x; s[0].y = p[0].y;
        s[1].x = p[1].x; s[1].y = p[1].y;
        int top=1;
        for(int i=2;i<n;i++) {
            while(top>=1 && cross(s[top-1],s[top],p[i]) < 0) top--;
            s[++top] = p[i];
        }
        double num = 0;
        for(int i=0;i<top;i++) {
            num += dis(s[i],s[i+1]);
        }
        num += dis(s[0],s[top]);
        num += (2*PI*l);
        printf("%.f\n",num);
    }
    return 0;
}

poj 2007 Scrambled Polygon
题意:按照一第一个输入的点排序。(读错题)
思路:极角排序下。

AC代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <map>
#include <cmath>
#include <string>
#include <stack>
#include <queue>
#include <vector>
#include <set>
const int  mod = 1e9+7;
#define ll long long
#define llu unsigned long long
using namespace std;
map<string,int>mp;
const int maxn = 100550+10;
const double eps = 0.0000001;
const double PI = 3.1415926;
int v[maxn],a[maxn];

struct Point {
    double x,y;
    Point(double x=0,double y=0):x(x),y(y){}
};
vector<Point>vec;
int n;
Point p[150];
Point p4[150],p3[150],p2[150],p1[150];
double cross(Point a,Point b,Point c) {
    return ((b.x-a.x)*(c.y-a.y) - (b.y-a.y)*(c.x-a.x));
}
double dis(Point a,Point b) {
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));

}

bool cmp(Point a,Point b) {
    if(a.x != b.x) return a.x<b.x;
    else return a.y<b.y;
}

bool cmp1(Point a,Point b) {
    double m = cross(p[0],a,b);
    if(fabs(m-0.0) <= eps) {
        if(dis(p[0],b) > dis(p[0],a)) return true;
        else return false;
    }
    else {
        if(m>0) return true;
        else return false;
    }
}

int main(){
//                freopen("1.in","r",stdin);
        scanf("%lf%lf",&p[0].x,&p[0].y);
        double tx = p[0].x,ty = p[0].y;
        int d = 0;
        int tp = 1;
        while(scanf("%lf%lf",&p[tp].x,&p[tp].y)!=EOF){tp++;}
        sort(p,p+tp,cmp);
        sort(p+1,p+tp,cmp1);
        for(int i=0;i<tp;i++) {
                if(p[i].x == tx && p[i].y == ty) {
                        d = i;
                        vec.push_back(p[i]);
                        break;
                }
        }
        for(int i=d+1;i<tp;i++) {
                vec.push_back(p[i]);
        }
        for(int i=0;i<d;i++) {
                vec.push_back(p[i]);
        }
        for(int i=0;i<vec.size();i++) {
                printf("(%.0f,%.0f)\n",vec[i].x,vec[i].y);
        }
        return 0;
}

poj 1228 Grandpa’s Estate
题意: 给n个点,问是不是一个稳定的凸包。
思路:第一次见这样的题,上网搜了一下,是让求稳定凸包。

AC代码:

//代码虽然ac了,但是有讨论区的数据过不去,还要更正。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <map>
#include <cmath>
#include <string>
#include <stack>
#include <queue>
#include <vector>
#include <set>
const int  mod = 1e9+7;
#define ll long long
#define llu unsigned long long
using namespace std;
map<string,int>mp;
const int maxn = 100550+10;
const double eps = 0.0000001;
const double PI = 3.1415926;

struct Point {
        double x,y;
        Point(double x=0,double y=0): x(x),y(y){}
};
Point p[1100],s[1100];
bool cmp(Point a,Point b){
        if(a.x!=b.x) return a.x < b.x;
        else return a.y < b.y;
}
double dis(Point a,Point b){
        return ((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double cross(Point a,Point b,Point c) {
                return ((b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x));
}
bool cmp1(Point a,Point b){
        double m = cross(p[0],a,b);
        if(fabs(m-0)<=eps) {
                if(dis(p[0],b) > dis(p[0],a)) return true;
                else return false;
        }else {
                if(m>0) return true;
                else return false;
        }
}
int main(){
//        freopen("1.in","r",stdin);
        int t; scanf("%d",&t);
        while(t--) {
                int n; scanf("%d",&n);
                for(int i=0;i<n;i++) {
                        scanf("%lf%lf",&p[i].x,&p[i].y);
                }
                if(n<=5) {
                        printf("NO\n"); continue;
                }
                sort(p,p+n,cmp);
                sort(p+1,p+n,cmp1);
                s[0].x = p[0].x; s[0].y = p[0].y;
                s[1].x = p[1].x; s[1].y = p[1].y;
                int top=1;
                for(int i=2;i<n;i++) {
                        while(top>=1 && cross(s[top-1],s[top],p[i])<0) top--;
                        s[++top] = p[i];
                }
//                for(int i=0;i<=top;i++) {
//                        printf("%lf      %lf\n",p[i].x,p[i].y);
//                }cout<<endl;
                bool pd = true;
                //判断是否是稳定凸包
                for(int i=1;i<top;i++) {
               //         printf("%lf      %lf\n",p[i].x,p[i].y);
                        if(cross(s[i-1],s[i],s[i+1])!=0 && cross(s[i],s[(i+1)>n?(i+1)%n : i+1],s[(i+2)>n?(i+2)%n : i+2])!=0) {
                                pd = false; break;
                        }
                }
                if(pd) printf("YES\n");
                else printf("NO\n");
        }
        return 0;
}

poj 3348 Cows

题意:给n个点,每50平米养一只,能养多少只。
思路:求凸包,在求个面积。

AC代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <map>
#include <cmath>
#include <string>
#include <stack>
#include <queue>
#include <vector>
#include <set>
const int  mod = 1e9+7;
#define ll long long
#define llu unsigned long long
using namespace std;
map<string,int>mp;
const int maxn = 100550+10;
const double eps = 0.0000001;
const double PI = 3.1415926;

struct Point {
        double x,y;
        Point(double x=0,double y=0): x(x),y(y){}
};
Point p[11000],s[11000];
bool cmp(Point a,Point b){
        if(a.x!=b.x) return a.x < b.x;
        else return a.y < b.y;
}
double dis(Point a,Point b){
        return ((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double cross(Point a,Point b,Point c) {
                return ((b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x));
}
bool cmp1(Point a,Point b){
        double m = cross(p[0],a,b);
        if(fabs(m-0)<=eps) {
                if(dis(p[0],b) > dis(p[0],a)) return true;
                else return false;
        }else {
                if(m>0) return true;
                else return false;
        }
}
int main(){
//        freopen("1.in","r",stdin);
        int n;
        while(scanf("%d",&n)!=EOF) {
                for(int i=0;i<n;i++) {
                        scanf("%lf%lf",&p[i].x,&p[i].y);
                }
                sort(p,p+n,cmp);
                sort(p+1,p+n,cmp1);
                s[0].x = p[0].x; s[0].y = p[0].y;
                s[1].x = p[1].x; s[1].y = p[1].y;
                int top = 1;
                for(int i=2;i<n;i++) {
                        while(top>=1 && cross(s[top-1],s[top],p[i])<=0) top--;
                        s[++top] = p[i];
                }
                double S = 0;
                for(int i=0;i<top;i++) {
                        S += abs(s[i].x*s[i+1].y-s[i+1].x*s[i].y);
                }
                S += abs(s[top].x*s[0].y - s[0].x*s[top].y);
                S = S/2;
//                printf("%lf\n",S);
                printf("%d\n",(int)S/50);
        }
        return 0;
}

推荐一道 poj1987 The Fortified Forest 题意简单,要状态压缩(可惜我太菜,还不会)。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值