• BAPC2014 C&&HUNNU11583:Citadel Construction(几何)


    题意:

    给出一系列的点,要求寻找最多4个点。使得组成一个面积最大的多边形


    思路:

    非常显然仅仅有两种情况。要么是三角形,要么是四边形

    首先不难想到的是。先要把最外面的点都找出来,事实上就是找凸包

    可是并没有做过凸包,那么怎么办?

    我们知道。ab与ac向量相乘得到ab*ac>=0的情况下。能够知道全部符合这个条件的。都固定在顺时针,那么我们能够通过这个,来求得全部外层的点

    得到这些点之后。我们就能够来找出答案了


    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <stack>
    #include <queue>
    #include <map>
    #include <set>
    #include <vector>
    #include <math.h>
    #include <bitset>
    #include <algorithm>
    #include <climits>
    using namespace std;
    
    #define ls 2*i
    #define rs 2*i+1
    #define UP(i,x,y) for(i=x;i<=y;i++)
    #define DOWN(i,x,y) for(i=x;i>=y;i--)
    #define MEM(a,x) memset(a,x,sizeof(a))
    #define W(a) while(a)
    #define gcd(a,b) __gcd(a,b)
    #define LL long long
    #define ULL unsigned long long
    #define N 1005
    #define INF 0x3f3f3f3f
    #define EXP 1e-8
    #define rank rank1
    const int mod = 1000000007;
    
    struct point
    {
        int x,y;
    } a[N],s[N];
    int t,n;
    
    int ads(int a)
    {
        return a<0?-a:a;
    }
    
    int mult(point a,point b,point c)
    {
        return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);
    }
    
    int cmp(point a,point b)
    {
        if(a.y==b.y)
            return a.x<b.x;
        return a.y<b.y;
    }
    
    int set1(point a[],int n,point s[])
    {
        int i,j,k;
        int top = 1;
        sort(a,a+n,cmp);
        if(n==0) return 0;
        s[0] = a[0];
        if(n==1) return 1;
        s[1] = a[1];
        if(n==2) return 2;
        s[2] = a[2];
        for(i = 2; i<n; i++)//先找右边的外层
        {
            while(top&&mult(a[i],s[top],s[top-1])>=0)//新进来的在顺时针方向,能够代替已保存在栈内的
                top--;
            s[++top] = a[i];
        }
        int len = top;
        s[++top] = a[n-2];
        for(i = n-3; i>=0; i--)//找左边的外层
        {
            while(top!=len&&mult(a[i],s[top],s[top-1])>=0)
                top--;
            s[++top] = a[i];
        }
        return top;
    }
    
    void solve()
    {
        int i,j,k,cnt,area;
        for(int i=0; i<n; i++)
            scanf("%d%d",&a[i].x,&a[i].y);
        cnt = set1(a,n,s);
        if(cnt<3)
        {
            printf("0
    ");
        }
        else if(cnt==3)
        {
            area = mult(s[2],s[1],s[0]);
            area = ads(area);
            if(area%2) printf("%d.5
    ",area/2);
            else printf("%d
    ",area/2);
        }
        else
        {
            area=-INF;
            s[cnt] = s[0];
            for(i = 0; i<cnt; i++)
            {
                int l = i,r = i+2;
                for(j = i+2; j<cnt; j++)//以i,j为四边形对角线。两边循环保证两个三角形不相交算出最大面积
                {
                    while(abs(mult(s[l+1],s[j],s[i]))>abs(mult(s[l],s[j],s[i]))) l = (l+1)%cnt;
                    int s1 = abs(mult(s[l],s[j],s[i]));
                    while(abs(mult(s[r+1],s[j],s[i]))>abs(mult(s[r],s[j],s[i]))) r = (r+1)%cnt;
                    int s2 = abs(mult(s[r],s[j],s[i]));
                    area = max(area,s1+s2);
                }
            }
            if(area%2) printf("%d.5
    ",area/2);
            else printf("%d
    ",area/2);
        }
    }
    
    int main()
    {
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            solve();
        }
    
        return 0;
    }
    


  • 相关阅读:
    jeos没有消亡,但看 debian 的 netinst .iso格式,那就是jeos的系统!
    ubuntu-14.04.x-desktop-amd64.iso:安装Oracle11gR2
    ubuntu-16.04.1-desktop-amd64.iso:ubuntu-16.04.1-desktop-amd64:安装Oracle11gR2
    JDBC 基础
    How to check for null/empty/whitespace values with a single test?
    STRING DELIMITED BY SIZE
    分行符
    甲醛超标
    notepad++ 去空行
    shell脚本中的set -e和set -o pipefail
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/7017968.html
Copyright © 2020-2023  润新知