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
    
    */
    成功的路并不拥挤,因为大部分人都在颓(笑)
  • 相关阅读:
    windows phone 7 中文天气预报应用来源http://www.cnblogs.com/liulunet/archive/2011/08/17/2141696.html
    Margin 属性的一些边界情况说明 转http://blog.csdn.net/ghj1976/article/details/4987686
    C#中的委托和事件(续)
    Windows Phone 7开发,进度条ProgressBar使用详解
    Silverlight BitmapImage的SetSource(Stream streamSource)致命性错误的解决办法
    Windows Phone 7 页面间传值 来源http://blog.csdn.net/dncts/article/details/6160067
    windows phone textblock C#设置颜色以及换行
    C# 中的委托和事件
    jsp连接Sql2008
    jsp连接Sql2008delete操作
  • 原文地址:https://www.cnblogs.com/SuuT/p/9518712.html
Copyright © 2011-2022 走看看