• HDU 4666


    http://acm.hdu.edu.cn/showproblem.php?pid=4666

    求m维最远曼哈顿距离

    借鉴别人的思路http://www.cnblogs.com/jackge/archive/2013/08/14/3256402.html

    以二维平面为例:

    设距离最远的两点为 i, j,可知所求的最大距离必定有以下四种形式之一:

    (xi-xj)+(yi-yj), (xj-xi)+(yi-yj), (xi-xj)+(yj-yi), (xj-xi)+(yj-yi) 变形一下,把相同点的坐标放到一起,

    即 (xi+yi)-(xj+yj), (-xi+yi)-(-xj+yj), (xi-yi)-(xj-yj), (-xi-yi)-(-xj-yj),可以发现即去绝对值之后把同一点的坐标放在一起,对应坐标符号相同。

    假如我们用0表示符号,用1表示正号,那么 (xi+yi) 可以表示为 11。

    由于在线并且有删除操作,最大最小值我们分别用两个堆来维护,枚举所有状态找出最大值即可

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <map>
    #include <algorithm>
    #include <queue>
    #include <cmath>
    #include <stack>
    #include <set>
    
    using namespace std;
    
    struct node1{
        int v,num;
        friend bool operator <(node1 a,node1 b){
            return a.v<b.v;
        }
    };
    
    struct node2{
        int v,num;
        friend bool operator <(node2 a,node2 b){
            return a.v>b.v;
        }    
    };
    
    int vis[60006];
    
    int main(){
        int q,m;
        while(~scanf("%d%d",&q,&m)){
            priority_queue <node1> h1[1<<5];
            priority_queue <node2> h2[1<<5];
            memset(vis,0,sizeof(vis));
            for(int i=1;i<=q;i++){
                int op;
                scanf("%d",&op);
                int a[6];
                if(!op){
                    for(int j=0;j<m;j++)
                        scanf("%d",&a[j]);
                    for(int j=0;j<(1<<m);j++){
                        int cnt=0;
                        for(int k=0;k<m;k++){
                            if(j&(1<<k)){
                                cnt+=a[k];
                            }
                            else{
                                cnt-=a[k];
                            }
                        }
                        node1 p1;
                        node2 p2;
                        p1.v=p2.v=cnt;
                        p1.num=i;p2.num=i;
                        h1[j].push(p1);
                        h2[j].push(p2);
                    }
                }
                else{
                    int x;
                    scanf("%d",&x);
                    vis[x]=1;
                }
                int ans=0;
                for(int j=0;j<(1<<m);j++){
                    node1 cnt1;
                    node2 cnt2;
                    int flag=0;
                    while(!h1[j].empty()){
                        cnt1=h1[j].top();
                        if(!vis[cnt1.num]){
                            flag++;
                            break;
                        }
                        h1[j].pop();
                    }
                    while(!h2[j].empty()){
                        cnt2=h2[j].top();
                        if(!vis[cnt2.num]){
                            flag++;
                            break;
                        }
                        h2[j].pop();
                    }
                    if(flag==2)ans=max(ans,cnt1.v-cnt2.v);
                }
                printf("%d
    ",ans);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    19面向对象--特殊成员
    18面向对象--成员和组合
    17面向对象--三大特性
    16异常处理
    15(os、random、sys、)(json、pickle )
    14python模块之re
    13正则表达式
    12内置函数补充,递归以及二分法。
    Linux环境ftp搭建及问题总结
    运维之路—linux忘记密码修改(rd.breake 方式)
  • 原文地址:https://www.cnblogs.com/xiaohongmao/p/4133410.html
Copyright © 2020-2023  润新知