zoukankan      html  css  js  c++  java
  • HDU

    第一次写计算几何,ac,感动。

    不过感觉自己的代码还可以美化一下。

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=5128

    题意:

    在一个坐标系中,有n个点,从中找到两个互不touch,互不cross的两个矩形(边要和坐标轴平行),使得面积最大。

    思路:

    枚举每个点,n的四次方,这题有个坑点是“回型矩阵”,是真的坑,然后discuss区里说的十字形矩阵是骗人的。

    每次对枚举的四个点进行check,如果两个矩阵的四个点相互不在对方的矩阵中,那么这组就是合法的。

    如果(这四个点组成一个回型矩阵),那么上面判check的结果就是,*一个矩阵的四个点在另一个矩阵中,而另一个矩阵没有*。

    注意**中的条件是必要条件,还有判断一下,这个回型矩阵中,有没有边重合。

    ac代码

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <map>
    #include <set>
    #include <queue>
    #include <list>
    #include <iterator>
    #include <cmath>
    using namespace std;
    
    #define lson (l , mid , rt << 1)
    #define rson (mid + 1 , r , rt << 1 | 1)
    #define debug(x) cerr << #x << " = " << x << "
    ";
    #define pb push_back
    #define pq priority_queue
    
    #define Pll pair<ll,ll>
    #define Pii pair<int,int>
    
    #define fi first
    #define se second
    
    #define OKC ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    typedef long long ll;
    typedef unsigned long long ull;
    
    
    /*-----------------show time----------------*/
    int n;
    int l[40],r[40];
    int mp[205][205];
    bool check(int i,int j,int x,int y)
    {
        int e[5][4];
        e[1][1] = l[i],e[1][2] = r[i];
        e[2][1] = l[i],e[2][2] = r[j];
        e[3][1] = l[j],e[3][2] = r[j];
        e[4][1] = l[j],e[4][2] = r[i];
        int le1 = min(l[x],l[y]),le2 = max(l[x],l[y]);
        int ri1 = min(r[x],r[y]),ri2 = max(r[x],r[y]);
        if(mp[l[x]][r[y]]==0||mp[l[y]][r[x]]==0)return false;
        for(int w=1; w<=4; w++)
        {
            if(mp[e[w][1]][e[w][2]]==0)return false;
            if(e[w][1]>=le1 && e[w][1] <= le2 && e[w][2]>=ri1 && e[w][2] <= ri2)
                return false;
        }
        return true;
    }
    /*
    bool tepan(int i,int j,int q,int w)
    {
        //1
        int l1 = min(l[i],l[j]),l2 = max(l[i],l[j]);
        int r1 = min(r[i],r[j]),r2 = max(r[i],r[j]);
    
        //2
    
        int x1 = min(l[q],l[w]),x2 = max(l[q],l[w]);
        int y1 = min(r[q],r[w]),y2 = max(r[q],r[w]);
    
        if(y1<r1 && y2>r2 && l1<x1 && l2 > x2)return true;
        if(y1>r1 && y2<r2 && l1>x1 && l2 < x2)return true;
        return false;
    }
    */
    int main(){
        while(~scanf("%d", &n)&&n){
            memset(mp,0,sizeof(mp));
            for(int i=1; i<=n; i++){
                scanf("%d%d", &l[i],&r[i]);
                mp[l[i]][r[i]] = 1;
            }
            int ans = 0;
            for(int i=1; i<=n; i++){
            for(int j=1; j<=n; j++){
            for(int q = 1; q<=n; q++){
            for(int w = 1; w<=n; w++){
    
                if(check(i,j,q,w)&&check(q,w,i,j)){
                    //if(tepan(i,j,q,w) ||tepan(q,w,i,j))continue;
                    if(l[i]==l[j]||r[i]==r[j]||l[q]==l[w]||r[q]==r[w])continue;
                    int tmp = abs(l[i]-l[j]) * abs(r[i] - r[j]) + abs(l[q]-l[w]) * abs(r[q] - r[w])  ;
                    ans = max (ans,tmp);    
                }    
                else if(check(i,j,q,w))
                {
                    if(l[i]==l[j]||r[i]==r[j]||l[q]==l[w]||r[q]==r[w])continue;
                    if(mp[l[q]][r[w]]==0||mp[l[w]][r[q]]==0)continue;
                    int tmp = abs(l[i]-l[j]) * abs(r[i] - r[j]) ;
                                // int tmp = max(tmp,)
                    int e[5][4];
                    e[1][1] = l[q],e[1][2] = r[q];
                    e[2][1] = l[q],e[2][2] = r[w];
                    e[3][1] = l[w],e[3][2] = r[w];
                    e[4][1] = l[w],e[4][2] = r[q];
                    int le1 = min(l[i],l[j]),le2 = max(l[i],l[j]);
                    int ri1 = min(r[i],r[j]),ri2 = max(r[i],r[j]);
                    int flag = 1;
                    for(int s = 1; s<=4;s++){                        //用于判断回字型的合法,里面完全包于
                        if(e[s][1]==le1||e[s][1]==le2||e[s][2]==ri1||e[s][2]==ri1){
                            flag = 0;
                            break;
                        }
                    }
                    if(flag)ans = max (ans,tmp);  
                    /*                            
                    if(tmp==3)                                      //样例一自己跑出3.发现了回型矩阵的奥秘;
                    {
                        cout<<"----------------"<<endl;
                        cout<<"zhe;"<<i<<" "<<j<<" "<<q<<" "<<w<<endl;                                                    
                        int e[5][4];
                        e[1][1] = l[i],e[1][2] = r[i];
                        e[2][1] = l[i],e[2][2] = r[j];
                        e[3][1] = l[j],e[3][2] = r[j];
                        e[4][1] = l[j],e[4][2] = r[i];
                        int le1 = min(l[q],l[w]),le2 = max(l[q],l[w]);
                        int ri1 = min(r[q],r[w]),ri2 = max(r[q],r[w]);
                        debug(le1);debug(le2);debug(ri1);debug(ri2);
                    }
                    */
                }
    
            }}}}        //这是四重循环的右括号
            if(ans == 0)puts("imp");
            else printf("%d
    ",ans);
        }
        return 0;
    }
    HDU5128
  • 相关阅读:
    众包兼职平台有哪些?
    提高页面速度的10种相对简单方法
    如何设计第三方账号登陆
    Nginx的配置参数中文说明
    确定你已经彻底搞懂Nginx了
    云编程,这是我见过最优雅的Web云端集成开发IDE-Cloud Studio
    Excel制作三级下拉菜单
    Excel多人共享
    spring_2_注入详解
    spring_1_工厂与第一个 Spring 程序
  • 原文地址:https://www.cnblogs.com/ckxkexing/p/9127503.html
Copyright © 2011-2022 走看看