营救公主

题描述 :
公主被魔王抓走了 , 王子需要拯救出美丽的公主 。 他进入了魔王的城
堡 , 魔王的城堡是一座很大的迷宫 。 为了使问题简单化 , 我们假设这个迷宫是一
个 N*M 的二维方格 。 迷宫里有一些墙 , 王子不能通过 。 王子只能移动到相邻 ( 上
下左右四个方向 ) 的方格内 , 并且一秒只能移动一步 , 就是说 , 如果王子在 (x,y )
一步只能移动到 (x-1,y),(x+1,y),(x,y-1),(x,y+1) 其中的一个位置上。地图由
‘S’,‘P’,‘ . ’ , ‘ *’ 四种符号构成 , ‘ . ’ 表示王子可以通过 , ‘ *’ 表示
墙,王子不能通过;'S'表示王子的位置;‘P’表示公主的位置; n表示公主存活的剩余时间,王子必须在 n 秒
内到达公主的位置,才能救活公主。

/** 
* 公主被魔王抓走了,王子需要拯救出美丽的公主。他进入了魔王的城堡,魔王的城堡是一座很大的迷宫。 
* 为了使问题简单化,我们假设这个迷宫是一个N*M的二维方格。迷宫里有一些墙,王子不能通过。王子只 
* 能移动到相邻(上下左右四个方向)的方格内,并且一秒只能移动一步。地图由’S’,’P’,’.’,’*’ 
* 四种符号构成,’.’表示王子可以通过,’*’表示墙,王子不能通过;’S’表示王子的位置;’P’表示公主 
* 的位置;T表示公主存活的剩余时间,王子必须在T秒内到达公主的位置,才能救活公主。如下图所示: 
*/

package com;

import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 公主被魔王抓走了,王子需要拯救出美丽的公主。他进入了魔王的城堡,魔王的城堡是一座很大的迷宫。
 * 为了使问题简单化,我们假设这个迷宫是一个N*M的二维方格。迷宫里有一些墙,王子不能通过。王子只
 * 能移动到相邻(上下左右四个方向)的方格内,并且一秒只能移动一步。地图由'S','P','.','*'
 * 四种符号构成,'.'表示王子可以通过,'*'表示墙,王子不能通过;'S'表示王子的位置;'P'表示公主
 * 的位置;T表示公主存活的剩余时间,王子必须在T秒内到达公主的位置,才能救活公主。如下图所示:
 */
public class SavePrincess
{
    private int m;
    private int n;
    private char[][] visited;
    private Map<Position, List<Position>> data = new HashMap<Position, List<Position>>();
    private int t;
    private Position s = null;
    private Position p = null;

    public static void main(String[] args)
    {
        char maze[][] = {
        /*        0    1    2    3    4    5    6    7    8    9*/
        /* 0 */{ '.', '*', '.', '.', '.', '*', '.', '.', '.', '.' },
        /* 1 */{ '.', 'S', '*', '.', '.', '.', '.', '.', '.', '.' },
        /* 2 */{ '.', '*', '*', '.', '.', '.', '.', '.', '.', '.' },
        /* 3 */{ '.', '.', '*', '*', '*', '.', '.', '.', '.', '.' },
        /* 4 */{ '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
        /* 5 */{ '.', '.', '.', '.', '*', '.', '.', '.', '.', '.' },
        /* 6 */{ '.', '.', '.', '.', '*', '.', '.', '.', '.', '.' },
        /* 7 */{ '.', '.', '.', '.', '*', '.', '.', '.', '.', '.' },
        /* 8 */{ '.', '.', '.', '.', '*', '.', '.', '.', '.', '.' },
        /* 9 */{ '.', '.', 'P', '.', '*', '.', '.', '.', '.', '.' } };

        // maze[][] = {
        // /* 0 1 2 3 4 5 6 7 8 9 */
        // /* 0 */{ '.', '.', '.', '*', '.', '.', '.', '.', '.', '.' },
        // /* 1 */{ '.', 'S', '*', '.', '.', '.', '.', '.', '.', '.' },
        // /* 2 */{ '.', '.', '*', '.', '.', '.', '.', '.', '.', '.' },
        // /* 3 */{ '.', '.', '*', '*', '.', '*', '.', '.', '.', '.' },
        // /* 4 */{ '.', '.', '.', '*', '.', '*', '.', '.', '.', '.' },
        // /* 5 */{ '.', '.', '.', '*', '.', '.', '.', '.', '.', '.' },
        // /* 6 */{ '.', '.', '*', '.', '.', '.', '.', '.', '.', '.' },
        // /* 7 */{ '.', '.', '*', '.', '*', '.', '*', '.', '.', '.' },
        // /* 8 */{ '.', '.', '.', '.', '*', '.', '*', '*', '*', '.' },
        // /* 9 */{ '.', '.', '*', '.', '*', '.', '*', 'P', '.', '.' } };

        new SavePrincess().saved(maze, 10, 8, 11);
    }

    /**
     * @param vis
     *            M行N列迷宫
     * @param m
     *            M
     * @param n
     *            N
     * @param t
     *            T 
     * 
     * @return boolean true表示营救成功,反之表示失败。
     */
    public boolean saved(char[][] vis, int m, int n, int t)
    {
        this.m = m;
        this.n = n;
        this.visited = vis;
        this.t = t;

        for (int i = 0; i != m; i++)
        {
            for (int j = 0; j != n; j++)
            {
                System.out.print(visited[i][j]);
                System.out.print(' ');
                Position tmp = new Position(i, j);
                switch (visited[i][j])
                {
                case '*':
                    break;
                case 'S':
                    this.s = tmp;
                    break;
                case '.':
                    prepareNode(i, j, tmp);
                    break;
                case 'P':
                    this.p = tmp;
                    prepareNode(i, j, tmp);
                default:
                    break;
                }
            }
            System.out.println("");
        }

        if (s == null || p == null)
        {
            System.out.println("input visited error!");
            return false;
        }

        Set<Position> excudedNode = new HashSet<Position>();
        int l = findNearstWay(p, excudedNode);

        if (l < 0)
        {
            System.out.println("failed saved the princess!");
            return false;
        }
        else
        {
            System.out.println("Saved the princess in " + l + " seconds!");
            return true;
        }

    }

    private int findNearstWay(Position p2, Set<Position> excudedNode)
    {
        if (s.equals(p2))
        {
            return 0;
        }

        
        List<Position> lst = data.get(p2);
        excudedNode.add(p2);

        int minLen = -1;
        if (lst == null)
        {
            return minLen;
        }
        for (Position o : lst)
        {
            if (excudedNode.contains(o))
            {
                continue;
            }
            
            int len = findNearstWay(o, excudedNode);
            
            if ((len <= this.t && len != -1) && (minLen == -1 || (minLen != -1 && len < minLen)))
            {
                minLen = len;
            }
        }

        excudedNode.remove(p2);
        if (minLen != -1)
        {
            return minLen + 1;
        }
        else
        {
            return minLen;
        }
    }

    private void prepareNode(int i, int j, Position tmp)
    {
        List<Position> lst1 = new LinkedList<Position>();
        addOneNode(i + 1, j, lst1);
        addOneNode(i, j + 1, lst1);
        addOneNode(i - 1, j, lst1);
        addOneNode(i, j - 1, lst1);
        if (!lst1.isEmpty())
        {
            data.put(tmp, lst1);
        }
    }

    private void addOneNode(int i, int j, List<Position> lst)
    {
        if (i >= m || i < 0 || j >= n || j < 0)
        {
            return;
        }

        switch (visited[i][j])
        {
        case '.':
        case 'S':
            lst.add(new Position(i, j));
            break;
        default:
            break;
        }
    }
}

package com;

public class Position implements Comparable<Position>
{
    private int i;
    private int j;

    public Position(int i, int j)
    {
        this.i = i;
        this.j = j;
    }

    @Override
    public int compareTo(Position o)
    {
        if (this.i == o.i && this.j == o.j)
        {
            return 0;
        }
        else if (this.i > o.i)
        {
            return 1;
        }
        else
        {
            if (this.i > o.j)
            {
                return 1;
            }
            else
            {
                return -1;
            }
        }
    }

    public boolean equals(Object o)
    {
        if (!(o instanceof Position))
        {
            return false;
        }

        if (this.compareTo((Position) o) == 0)
        {
            return true;
        }

        return false;
    }

    public int hashCode()
    {
        int result = 17;
        result = 31 * result + i;
        result = 31 * result + j;
        return result;
    }

    public String toString()
    {
        return "(" + i + ", " + j + ")";
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值