zoukankan      html  css  js  c++  java
  • [BZOJ 1193] 马步距离

    Link:https://www.lydsy.com/JudgeOnline/problem.php?id=1193

    Solution:

    能立刻看出贪心算法,但发现在小数据时明显不适用

    于是我们采取大数据时贪心,到一定范围时爆搜的算法

    (似乎有点像AlphaGo的策略?)

    在数据大于10时,我们每次将长边-2,短边-1,如有小于0的情况取绝对值即可(相当于选用对称方案)

    用BFS预处理出数据<=10时的情况即可

    Code:

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef pair<int,int> P;
    
    int X1,Y1,X2,Y2,dist[105][105];
    int dx[]={-2,-2,-1,-1,1,1,2,2},dy[]={1,-1,2,-2,2,-2,1,-1};
    queue<P> que;
    
    void init()
    {
        memset(dist,0x3f,sizeof(dist));
        dist[1][1]=0;que.push(P(1,1));
        while(!que.empty())
        {
            P t=que.front();que.pop();
            for(int i=0;i<8;i++)
            {
                int fx=t.first+dx[i],fy=t.second+dy[i];
                if(fx<0 || fx>12 || fy<0 || fy>12) continue;
                if(dist[fx][fy]>dist[t.first][t.second]+1)
                    dist[fx][fy]=dist[t.first][t.second]+1,que.push(P(fx,fy));
            }
        }
    }
    
    int main()
    {
        init();
        scanf("%d%d%d%d",&X1,&Y1,&X2,&Y2);
        int a=abs(X1-X2),b=abs(Y1-Y2),res=0;
        while((a>=10) || (b>=10))
        {
            if(a>b) swap(a,b);
            a-=1;b-=2;res++;
            a=abs(a);b=abs(b);
        }
        a++;b++;
        
        printf("%d",res+dist[a][b]);
        return 0;
    }

    Review:

    1、如仅有适用于大数据时的贪心算法时,

    考虑大数据时贪心,到满足时间复杂度时开始爆搜(很不错的思想)

    2、能向各个方向移动的问题

    如将数组左上角作为起点,一定要将边界空间留出(有时最优解需要往回走)

    ex:此处第0行/列都是合法的,而-1行则可由第3行代替,便可不必考虑

    更稳妥的方式是将起点设在中间,如(50,50)

  • 相关阅读:
    STL之vector
    [洛谷P3942] 将军令
    [洛谷P2127] 序列排序
    [USACO07FEB]新牛棚Building A New Barn
    [洛谷P1120] 小木棍 [数据加强版]
    [洛谷P1438] 无聊的数列
    我的Emacs配置
    [CQOI2015]任务查询系统
    可持久化数组入门
    学习openstack(六)
  • 原文地址:https://www.cnblogs.com/newera/p/9094650.html
Copyright © 2011-2022 走看看