zoukankan      html  css  js  c++  java
  • HDU 4539 郑厂长系列故事――排兵布阵(曼哈顿距离)

    这虽然是中文题,然而没看懂,不懂的地方,就是在曼哈顿距离这块,网上搜索了一下,写了个程序,是测试曼哈顿距离的。

    曼哈顿距离:两点(x1,y1)(x2,y2)的曼哈顿距离为|x1-x2|+|y1-y2|

    测试代码:

    #include <map>
    #include <set>
    #include <list>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <cstdio>
    #include <string>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    const int INF=0x3f3f3f3f;
    typedef long long ll;
    typedef unsigned long long ull;
    #define fi first
    #define se second
    #define prN printf("
    ")
    #define SI(N) scanf("%d",&(N))
    #define SII(N,M) scanf("%d%d",&(N),&(M))
    #define SIII(N,M,K) scanf("%d%d%d",&(N),&(M),&(K))
    #define cle(a,val) memset(a,(val),sizeof(a))
    #define rep(i,b) for(int i=0;i<(b);i++)
    #define Rep(i,a,b) for(int i=(a);i<=(b);i++)
    
    
    char tu[60][60];
    int a[100][2];
    int main()
    {
    #ifndef ONLINE_JUDGE
    //    freopen("C:\Users\Zmy\Desktop\in.txt","r",stdin);
    //    freopen("C:\Users\Zmy\Desktop\out.txt","w",stdout);
    #endif // ONLINE_JUDGE
    
    
        int i=2,i1=3;
        int p=0;
        rep(j,6)
        rep(j1,6)
        {
            if (abs(i-j)+abs(i1-j1)==2)
            {
                printf("%d %d
    ",j,j1);
                a[p][0]=j;
                a[p++][1]=j1;
            }
        }
        
        
    //     i=2,i1=2;
    //    rep(j,6)
    //    rep(j1,6)
    //    {
    //        if (abs(i-j)+abs(i1-j1)==2)
    //        {
    //            printf("%d %d
    ",j,j1);
    //            a[p][0]=j;
    //            a[p++][1]=j1;
    //        }
    //    }
    
    
        cle(tu,'.');
        rep(i,p)
        {
    
            tu[a[i][0]][a[i][1]]='*';
        }
    
        rep(i,6)
        {
            rep(j,6)
            {
                printf("%c ",tu[i][j]);
            }
            prN;
        }
    
        return 0;
    }

    这是根据测试样例的背景写的,i,i1是所给坐标,最后输出*的地方,就是他对应的曼哈顿距离 (由图可知:曼哈顿距离就是以这个点为中心的菱形)

    AC代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #define N 110
    #define M 200
    
    
    using namespace std;
    
    
    int n,m,a[N];
    int dp[N][M][M],cnt,num[M],sum[M];
    ///dp[i][j][k]  表示第i行的j状态 i-1行的k状态 的最优解
    
    
    bool ok(int x)
    {
        return (x&(x<<2))||(x&(x<<2));///第x-2个和x+2个位是否有人,
        // 有的话就不符合条件
    }
    
    
    int getsum(int x)    ///1的个数,即放多少个兵
    {
        int sum=0;
        while(x)
        {
            if(x&1)sum++;
            x>>=1;
        }
        return sum;
    }
    
    
    void init()
    {
        cnt=0;
        for(int i=0; i<(1<<m); i++)   ///预处理,压缩
        {
            if(!ok(i))
            {
                num[cnt]=i;
                sum[cnt++]=getsum(i);
            }
        }
    }
    ////二进制函数
    //int two[100];
    //void o_two(int n)
    //{
    //    memset(two,0,sizeof(two));
    //    int p=1;
    //    while(n)
    //    {
    //        two[p++]=n%2;
    //        n/=2;
    //    }
    //    printf("Two:");
    //    for (int i=12;i>=1;i--)
    //    {
    //        if (i%4==0)
    //            printf("  ");
    //        printf("%d ",two[i]);
    //    }puts("");
    //}
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("C:\Users\Zmy\Desktop\in.txt","r",stdin);
    //    freopen("C:\Users\Zmy\Desktop\out.txt","w",stdout);
    #endif // ONLINE_JUDGE
        while(~scanf("%d%d",&n,&m))
        {
            memset(a,0,sizeof a);
            for(int i=0; i<n; i++)
            {
                for(int j=0; j<m; j++)
                {
                    int x;
                    scanf("%d",&x);
                    if(x)continue;///方便计算,把0存为1
                    a[i]|=(1<<j);
                }
            }
    //        for (int i=0;i<n;i++)
    //            o_two(a[i]);
            init();///初始化了num(情况数组)和sum(个数数组)
            memset(dp,0,sizeof dp);
            for(int i=0; i<cnt; i++)   ///处理第一行
            {
                if(a[0]&num[i])continue;
                dp[0][i][0]=sum[i];
            }
    
    
            ///递推,要考虑三行的情况,
            for(int i=1; i<n; i++)   //第一行
            {
                for(int j=0; j<cnt; j++)
                {
                    if(a[i]&num[j])continue;   ///第一行与原来矩阵有冲突
                    for(int k=0; k<cnt; k++)     ///第二行
                    {
                        if(a[i-1]&num[k])continue;
                        if(((num[k]<<1)&num[j])||((num[k]>>1)&num[j]))continue; //i-1行
                        int Max=-1;
                        for(int l=0; l<cnt; l++)         ///第三行
                        {
                            if(num[j]&num[l])continue;
                            if(((num[l]<<1)&num[k])||((num[l]>>1)&num[k]))continue;
                            Max=max(Max,dp[i-1][k][l]);
                        }
                        dp[i][j][k]=Max+sum[j];
                    }
                }
            }
            int Max=-1;
            for(int i=0; i<cnt; i++)
                for(int j=0; j<cnt; j++)
                    Max=max(Max,dp[n-1][i][j]);
            printf("%d
    ",Max);
        }
        return 0;
    }
    

      

  • 相关阅读:
    powershel学习(1)
    JS作用域链(转载)
    C# 对QuotedPrintable进行解码的方法
    SortedList、SortedSet、HashSet、Hashtable、Dictionary、SortedDictionary 排序/可重复排序/过滤重复排序等简单对比
    .net windows 服务中返回服务的安装目录
    c# 中图像的简单二值化处理
    windows下开多个CMD窗口多个进程输出
    生命游戏
    PowerDesigner工具简介
    七大面向对象设计原则(转)
  • 原文地址:https://www.cnblogs.com/s1124yy/p/5520983.html
Copyright © 2011-2022 走看看