zoukankan      html  css  js  c++  java
  • hdu6435 Problem J. CSGO标程讲解以及改正标程的一个错误(本来第一个样例过不了2333) 以及 poj2926 五维曼哈顿距离模板

    比赛的时候抄poj2926的模板,但改不来啊orz

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    const int dem=5;        //维数
    const int maxxn=100005;
    const double inf=1e200;
    struct Point{
        double x[dem];
    }p[maxxn];
    int n;
    double minx[1<<dem], maxx[1<<dem];
     
    double solve(){
        int i, j, k, t, tmp=1<<dem;
        double s, ans=-inf;
        for(i=0; i<tmp; i++){
            minx[i]=inf;
            maxx[i]=-inf;
        }
        for(i=0; i<n; i++){
            for(j=0; j<tmp; j++){
                t=j;s=0;
                for(k=0; k<dem; k++){
                    if(t&1)
                    s+=p[i].x[k];
                    else s-=p[i].x[k];
                    t>>=1;
                }
                if(maxx[j]<s)maxx[j]=s;
                if(minx[j]>s)minx[j]=s;
            }
        }
        for(i=0; i<tmp; i++){
            if(maxx[i]-minx[i]>ans)
            ans=maxx[i]-minx[i];
        }
        return ans;
    }
    int main(){
        //freopen("1.txt", "r", stdin);
        int i, j;
        while(scanf("%d", &n)!=EOF){
            for(i=0; i<n; i++){
                for(j=0; j<dem; j++)
                    scanf("%lf", &p[i].x[j]);
            }
            printf("%.2f
    ", solve());
        }
        return 0;
    }
    View Code

     后来看了标程,感觉上面那个算法是瞎搞的,于是改成了正确的姿势:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include<ctime>
    using namespace std;
    #define LL double
    
    int T, n, m, K  ;
    LL A[64], B[64], Ans,val,x[6];
    
    int main()
    {
        int i, k, S;
    
    
            K=5;
            cin>>n;
            Ans = 0;
            for (int i = 0; i < 64; i++)A[i] = B[i] = -1e200;
    
            for (i = 1; i <= n; i++)
            {
    
                for (k = 0; k<K; k++)
                    scanf("%lf", &x[k]);
                for (S = 0; S<1 << K; S++)
                {
                    LL Sum = 0;
                    for (k = 0; k<K; k++)
                        Sum += x[k] * ((((S >> k) & 1) << 1) - 1);
                    A[S] = max(A[S], Sum);
                }
            }
    
    
            for (S = 0; S<1 << K; S++)
                {Ans = max(Ans, A[S] + A[(1 << K) - 1 - S]);
                }
            printf("%.2lf
    ", Ans);
    
    }
    /*
    3
    2 5 6 2 1.5
    1.2 3 2 5 4
    7 5 3 2 5
    
    */
    View Code

    这个程序的二进制操作比较秀,具体来说:

    ((((S >> k) & 1) << 1) - 1)这一句是if(S的第k位为1)f=1; else f=-1 的缩写(感觉反而更麻烦了233)

    A[S] + A[(1 << K) - 1 - S]这一句的意思是把符号相反的一组最优向量加起来。因为(1 << K) - 1 - S与S的0,1 互补,对应向量里+、- 互补。

    标程唯一被hack的地方是数组初始化时用了memset,应该全部赋值为-inf

    下面给出标程(改了一句)

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include<ctime>
    using namespace std;
    #define LL long long
    
    int T, n, m, K, val, x[6];
    LL A[64], B[64], Ans;
    
    int main()
    {
        int i, k, S;
        scanf("%d", &T);
        while (T--)
        {
            scanf("%d%d%d", &n, &m, &K);
            Ans = 0;
            //memset(A, 0, sizeof(A));
            //memset(B, 0, sizeof(B));
            for (int i = 0; i < 64; i++)A[i] = B[i] = -1e18;
            for (i = 1; i <= n; i++)
            {
                scanf("%d", &val);
                for (k = 0; k<K; k++)
                    scanf("%d", &x[k]);
                for (S = 0; S<1 << K; S++)
                {
                    LL Sum = val;
                    for (k = 0; k<K; k++)
                        Sum += x[k] * ((((S >> k) & 1) << 1) - 1);
                    A[S] = max(A[S], Sum);
                }
            }
    
            for (i = 1; i <= m; i++)
            {
                scanf("%d", &val);
                for (k = 0; k<K; k++)
                    scanf("%d", &x[k]);
                for (S = 0; S<1 << K; S++)
                {
                    LL Sum = val;
                    for (k = 0; k<K; k++)
                        Sum += x[k] * ((((S >> k) & 1) << 1) - 1);
                    B[S] = max(B[S], Sum);
                }
            }
    
            for (S = 0; S<1 << K; S++)
                Ans = max(Ans, A[S] + B[(1 << K) - 1 - S]);
            printf("%lld
    ", Ans);
        }
    }
    
    
    
    /*
    1
    2 2 1
    0 1
    0 2
    0 4
    0 3
    
    2
    2 2 1
    0 233
    0 666
    0 123
    0 456
    2 2 1
    100 0 1000 100 1000 100
    100 0
    
    */
    成功的路并不拥挤,因为大部分人都在颓(笑)
  • 相关阅读:
    团队项目-第一阶段冲刺7
    团队项目-第一阶段冲刺6
    Spring Boot 揭秘与实战(七) 实用技术篇
    Spring Boot 揭秘与实战(七) 实用技术篇
    Spring Boot 揭秘与实战(六) 消息队列篇
    Spring Boot 揭秘与实战(五) 服务器篇
    Spring Boot 揭秘与实战(五) 服务器篇
    Spring Boot 揭秘与实战(五) 服务器篇
    Spring Boot 揭秘与实战(五) 服务器篇
    Spring Boot 揭秘与实战(四) 配置文件篇
  • 原文地址:https://www.cnblogs.com/SuuT/p/9518712.html
Copyright © 2011-2022 走看看