zoukankan      html  css  js  c++  java
  • uva1331 Minimax Triangulation

    题目大意:

    按照顺时针或者逆时针的顺序给出多边的点,要将这个多边形分解成n-2个三角形,要求使得这些三角行中面积最大的三角形面积尽量小,求最小值。

    /*
        dp[i][j]表示从第i个点到第j个点,划分成j-i-1个三角形的最优解,然后每次转移时,枚举长度和左边界始点,那么根据长度和左边界点就可以知道右边界点,然后枚举左边界和右边界中间的点k,dp[i][j] = min(dp[i][j], max(max(dp[i][k], dp[k][j]), Area(i, k, j)).但是有一个问题,即i,k,j三点围成的三角形是否符合要求,判断的条件即为是否存在除i,k,j三点外的一点位于三角形中,有面积法判断。
    */
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    
    using namespace std;
    const int N = 100;
    const double INF = 0x3f3f3f3f3f3f;
    const double eps = 1e-9;
    
    struct point {
        double x, y;
        void get() {
            scanf("%lf%lf", &x, &y);
        }
    }p[N];
    
    int n;
    double dp[N][N];
    
    double area (point a, point b, point c) {
        return fabs((b.x-a.x)*(c.y-a.y) - (c.x-a.x)*(b.y-a.y))/2;
    }
    
    bool judge(int a,int b,int c) {//是否存在除i,k,j三点外的一点位于三角形中 
        double cur=area(p[a],p[b],p[c]);
        for(int i=0;i<n;i++) {
            if(i==a||i==b||i==c)
                continue;
            double tmp=area(p[a],p[b],p[i])+area(p[b],p[c],p[i])+area(p[c],p[a],p[i]);
            if(fabs(tmp-cur)<eps)
                return false;
        }
        return true;
    }
    
    double solve () {
        for (int i = 0; i < 2; i++) {
            for (int j = 0; j < n; j++)
                dp[j][(j+i)%n] = 0;
        }
    
        for (int i = 0; i < n; i++)
            dp[i][(i+2)%n] = area(p[i], p[(i+1)%n], p[(i+2)%n]);
        for(int k=3;k<n;k++){
                for(int i=0;i<n;i++){
                    int t=(i+k)%n;
                    dp[i][t]=INF;
                    for(int j=(i+1)%n;j!=t;j=(j+1)%n){
                        if(judge(i,t,j))dp[i][t]=min(dp[i][t],max(max(dp[i][j],dp[j][t]),area(p[i], p[j], p[t])));
                    }
                }
            }
    
        double ans = INF;
        for (int i = 0; i < n; i++)
            ans = min (ans, dp[i][(i+n-1)%n]);
        return ans;
    }
    
    int main () {
        freopen("Cola.in","r",stdin);
        int cas;
        scanf("%d", &cas);
        while (cas--) {
            scanf("%d", &n);
            for (int i = 0; i < n; i++)
                p[i].get();
    
            printf("%.1lf
    ", solve());
        }
        return 0;
    }
    100分
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    using namespace std;
    int t,n;
    const double INF = 0x3f3f3f3f3f3f;
    const double eps = 1e-9;
    double s[60][60][60],dp[60][60];
    struct node{
        double x,y;
    }pos[60];
    double count(int i,int j,int k){//计算面积 
        double x1=pos[i].x,x2=pos[j].x,x3=pos[k].x;
        double y1=pos[i].y,y2=pos[j].y,y3=pos[k].y;
        double xx1=x1-x3,xx2=x2-x3;
        double yy1=y1-y3,yy2=y2-y3;
        double res=fabs((xx1*yy2-xx2*yy1)/2.0);
        return res;
    }
    bool judge(int a,int b,int c){
        double cur=s[a][b][c];
        for(int i=1;i<=n;i++){
            if(i==a||i==b||i==c)continue;
            double tmp=s[a][b][i]+s[a][c][i]+s[b][c][i];
            if(fabs(tmp-cur)<=eps)return 0;
        }
        return 1;
    }
    int main(){
        freopen("Cola.in","r",stdin);
        scanf("%d",&t);
        while(t--){
            scanf("%d",&n);
            memset(s,0,sizeof(s));
            memset(dp,0,sizeof(dp));
            for(int i=0;i<n;i++)scanf("%lf%lf",&pos[i].x,&pos[i].y);
            for(int i=0;i<n;i++)
                for(int j=0;j<n;j++)
                    for(int k=0;k<n;k++){
                        //s[i][j][k]=INF;
                        if(i!=j&&i!=k&&j!=k)
                            s[i][j][k]=count(i,j,k);
                    }
                        
            for(int i=0;i<n;i++)dp[i][(i+2)%n]=s[i][(i+1)%n][(i+2)%n];
            for(int k=3;k<n;k++){
                for(int i=0;i<n;i++){
                    int t=(i+k)%n;
                    dp[i][t]=INF;
                    for(int j=(i+1)%n;j!=t;j=(j+1)%n){
                        if(judge(i,t,j))dp[i][t]=min(dp[i][t],max(max(dp[i][j],dp[j][t]),s[i][j][t]));
                    }
                }
            }
            double ans=INF;
            for(int i=0;i<n;i++)
            ans=min(ans,dp[i][(i+n-1)%n]);
            printf("%.1lf
    ",ans);
        }
    } 
    wa 预处理了所有三角形的面积就迷之wa了
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<ctime>
    using namespace std;
    int t,n;
    int main(){
        srand(time(0));
        t=rand()%6+2;
        printf("%d
    ",t);
        while(t--){
            n=rand()%3+3;
            printf("%d
    ",n);
            for(int i=1;i<=n;i++){
                int x=rand()%20+1,y=rand()%20+1;
                printf("%d %d
    ",x,y);
            }
        }
    }
    data 造小数据
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<windows.h>
    using namespace std;
    int main(){
        int t=1000000;
        while(t--){
            system("1331_data>Cola.in");
            system("1331_thmyl<Cola.in>1.out");
            system("1331_std<Cola.in>2.out");
            if(system("fc 1.out 2.out"))break;
        }
        system("pause");
    }
    对拍
  • 相关阅读:
    begin lydsy 2731
    关于js中this关键字的补充
    js中this关键字测试集锦
    js文件中函数前加分号和感叹号是什么意思?
    好用的wget命令从下载添加环境变量到各参数详解
    一个解析json串并组装echarts的option的函数解析
    oschina代码仓库远程push,pull免密实操总结
    yii 核心类classes.php详解(持续更新中...)
    yii2.0归档安装方法
    配置windows 系统PHP系统环境变量
  • 原文地址:https://www.cnblogs.com/thmyl/p/7411908.html
Copyright © 2011-2022 走看看