• coj 1224 ACM小组的古怪象棋


    这道题的变态之处在于有下述的“蹩蹄”的情况出现,据不完全统计,24次非WA提交中,有15次左右是我的,多亏了LJ大牛及时指出这道题的陷阱。

    BFS或者DP,要注意会出现“蹩蹄”的情况(题目提都没提)。

    DP相对容易一些(记忆化搜索),要注意的一点是可能出现马永远无法到达将的位置,这时可能会出现两个状态相互调用以致出现死循环,解决的办法是:初始化时所有状态都定义为-1(将的位置定义为0,因为不许要移动),在求当前状态时,如果没有搜索过,首先将该状态置为+INF,这样及时无法搜索道,当结束时,依然为INF……这样对吗?

    经过验证,发现只要棋盘的行和列都大于等于4,那么马可以从任意位置出发经若干步到达任意指定位置。

    # include <stdio.h>
    # include <memory.h>
    # include <math.h>
    
    # define INF (0x1<<30)
    # define MIN(x,y) ((x)<(y) ? (x):(y))
    
    typedef struct {
        int x, y;
    }Point;
    
    int n, m;
    Point horse, king;
    int f[25][25];
    
    const Point d[8] = {{1,2}, {2,1}, {2,-1}, {1,-2}, {-1,-2}, {-2,-1}, {-2,1}, {-1,2}};
    
    int dp(Point s);
    int check(Point cur, Point tmp, int dir);
    
    int main()
    {
        int ans, i, j;
    
        while (~scanf("%d%d%d%d%d%d", &n, &m, &king.x, &king.y, &horse.x, &horse.y))
        {
            memset(f, -1, sizeof(f));
            f[king.x][king.y] = 0;
    
            ans = dp(horse);
            if (ans >= INF) printf("-1\n");    /* 会返回INF吗?有待思考 */
            else printf("%d\n", ans);
        }
    
        return 0;
    }
    
    int check(Point cur, Point tmp, int dir)
    {
        if (tmp.x <= 0 || tmp.x > n || tmp.y <= 0 || tmp.y > m) return 0;
        if (abs(d[dir].x) == 2 && cur.y == king.y && (tmp.x-king.x)*(cur.x-king.x)<0) return 0;
        if (abs(d[dir].y) == 2 && cur.x == king.x && (tmp.y-king.y)*(cur.y-king.y)<0) return 0;
        return 1;
    }
    
    int dp(Point s)
    {
        int i;
        Point tmp;
    
        if (f[s.x][s.y]>=0) return f[s.x][s.y];
        f[s.x][s.y] = INF;
        for (i = 0; i < 8; ++i)
        {
            tmp.x = s.x + d[i].x;
            tmp.y = s.y + d[i].y;
            if (check(s, tmp, i))
            {
                f[s.x][s.y] = MIN(f[s.x][s.y], dp(tmp)+1);
            }
        }
    
        return f[s.x][s.y];
    }
  • 相关阅读:
    心得sql空值的应用
    C#开发GIS应用简明教程(二)
    网页右下角弹出窗口
    弹出输入框方法汇总
    C#开发GIS应用简明教程(三)
    防刷新的另一种方法
    相册
    网站下载速度限制方法
    .NET下多线程初探
    用DECODE做交叉报表
  • 原文地址:https://www.cnblogs.com/JMDWQ/p/2446197.html
Copyright © 2020-2023  润新知