Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

这么做

Posted by zhangxiao1124 at 2008-05-02 17:54:15 on Problem 1259 and last updated at 2008-05-02 17:54:32
/*
    枚举左下角
    然后f[i][j]用来表示以点i,点j为凸包最后两个点的最大面积 
*/
#include<iostream>
using namespace std;
#define maxn 101
#define sqr(x) ((x)*(x))
#define Inf 1e30
inline int Cross_Product(int x_1,int y_1,int x_2,int y_2) {
    return x_1*y_2-x_2*y_1;
}
struct Point {
    int x,y;
    void Readin() {
        scanf("%d%d",&x,&y);
    }
    void Minus(Point s) {
        x-=s.x,y-=s.y;
    }
    bool In(Point a,Point b) {
        int r1=Cross_Product(-x,-y,a.x-x,a.y-y);
        int r2=Cross_Product(a.x-x,a.y-y,b.x-x,b.y-y);
        int r3=Cross_Product(b.x-x,b.y-y,-x,-y);
        return (r1>0 && r2>0 && r3>0 || r1<0 && r2<0 && r3<0);
    }
} p[maxn],q[maxn],s;
int n,m;
bool done[maxn][maxn];
double ans,rec[maxn][maxn];

int Compare_Horizontal(const void *a,const void *b) {
    if (((Point*)a)->y==((Point*)b)->y) return ((Point*)a)->x-((Point*)b)->x;
    return ((Point*)a)->y-((Point*)b)->y;
}

int Compare_Angle(const void *a,const void *b) {
    int x_1=((Point*)a)->x,y_1=((Point*)a)->y;
    int x_2=((Point*)b)->x,y_2=((Point*)b)->y;
    int tmp=Cross_Product(x_1,y_1,x_2,y_2);
    if (tmp) return -tmp;
    return -( sqr(x_1)+sqr(y_1)-sqr(x_2)-sqr(y_2) );
}

void Init() {                                           //读入并且排水平序 
    scanf("%d",&n);
    for (int i=0; i<n; i++) p[i].Readin();
    qsort(p,n,sizeof(Point),Compare_Horizontal);
    ans=0.0;
}

double f(int i,int j) {                                      
    if (done[i][j]) return rec[i][j];
    done[i][j]=true;
    for (int k=i+1; k<j; k++)                                       //判断状态是否合法 
        if (q[k].In(q[i],q[j])) {
            rec[i][j]=-Inf;
            return rec[i][j];
        }
    rec[i][j]=Cross_Product(q[i].x,q[i].y,q[j].x,q[j].y)*0.5;       //向前转移 
    if (!Cross_Product(q[i].x,q[i].y,q[j].x,q[j].y) || Cross_Product(q[i].x,q[i].y,q[i+1].x,q[i+1].y)) {
        double tmp=0.0;
        for (int k=0; k<i; k++)
            if (Cross_Product(q[i].x-q[j].x,q[i].y-q[j].y,q[k].x-q[i].x,q[k].y-q[i].y)<=0) tmp>?=f(k,i);
        rec[i][j]+=tmp;
    }
    return rec[i][j];
}

void Dp() {
    memset(done,0,sizeof(done));
    memset(rec,0,sizeof(rec));
    for (int i=0; i<m-1; i++)
        for (int j=i+1; j<m; j++) ans>?=f(i,j);
}

void Work() {                                               //枚举凸包的左下角 
    for (int i=0; i<n-2; i++) {
        s=p[i];
        m=n-1-i;
        for (int j=0; j<m; j++) q[j]=p[j+i+1];
        for (int j=0; j<m; j++) q[j].Minus(s);              //把后面的点都拿出来,再排极角序 
        qsort(q,m,sizeof(Point),Compare_Angle);
        Dp();                                               //动态规划 
    }
}

int main() {
    int test;
    for (scanf("%d",&test); test; test--) {
        Init();
        Work();
        printf("%.1lf\n",ans);
    }
    return 0;
}

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator