同一个世界 编码寻找解决方案

TapTap最近推荐的一款游戏《同一个世界》,感觉挺好玩的,就是有点难,尝试着写代码找个解决方案!
定义:
1(Point).一个点有true,false,null三种状态,每个点都有一个坐标;
2(OneWorld).一张图由一个二维数组组成;
3(OneWorld).当图中的点状态除null外,只有true或者false时,认为图是完美的(isPerfact);
4(OneStep).图从起点开始行走,走一步,形成一张新的图和行走的路径steps;

解决方案:(递归)
图从起点开始走一步,判断图是否完美(isPerfact);如果完美返回当前的路径(OneStep),否则接着走下一步;直到perfact或者不能走下一步!

ps:能用,但是效率感人!!!(代码中的测试用例,在调用i5 25%的cpu,700M的内存,跑了700秒!);
pps:欢迎交流!

Point.java


/**
 * 每个点都有一个值,默认为null;<br>
 * 每个点都有一个坐标,默认为[0,0]
 */
public class Point {
    // 对于一个点:有ture,false null 三种状态
    // null表示不存在
    private Boolean value = null;
    // 每一个点都有一个坐标
    private int x = 0;
    private int y = 0;

    public Point() {
    }

    public Point(Boolean value) {
        this.value = value;
    }

    public Point(Boolean value, int x, int y) {
        super();
        this.value = value;
        this.x = x;
        this.y = y;
    }

    public Point copy() {
        return new Point(this.value, this.x, this.y);
    }

    // 改变值;
    public Boolean changeValue() {
        value = value == null ? null : !value;
        return value;
    }

    public Boolean getValue() {
        return value;
    }

    public void setValue(Boolean value) {
        this.value = value;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

}

OneWorld.java

package world;

import java.util.ArrayList;
import java.util.List;

/**
 * 特性从起点的顺序和走的步骤无关,每一个起点走的步骤固定;每个步骤没有先后联系
 */
public class OneWorld {
    private Point[][] oneWorld;
    private Point[] start;
    private int num = Constant.X * Constant.Y;// 点的值为非null的数据,默认为全部
    private int trueNum = 0;// 点中值为true的数目

    public int getTrueNum() {
        return trueNum;
    }

    public int getNum() {
        return num;
    }

    public OneWorld(Point[][] oneWorld, Point... start) {
        this.oneWorld = oneWorld;
        this.start = start;
        perDeal();
    }

    private OneWorld() {
    }

    // 处理num和trueNum字段
    public void perDeal() {
        for (int i = 0; i < Constant.X; i++) {
            for (int j = 0; j < Constant.Y; j++) {
                if (oneWorld[i][j].getValue() == null) {
                    num--;
                } else if (oneWorld[i][j].getValue() == true) {
                    trueNum++;
                }
            }
        }
    }

    // 获取point
    public Point getPoint(int x, int y) {
        return oneWorld[x][y];
    }

    // 获取point的复制
    public Point getPointCopy(int x, int y) {
        return oneWorld[x][y].copy();
    }

    // 改变point的值
    public void ChangePoint(int x, int y) {
        Point point = oneWorld[x][y];
        point.changeValue();
        if (point.getValue() == true) {
            trueNum++;
        } else {
            trueNum--;
        }

    }

    /**
     * 当图中的点,值只有null和另外一种的时候,图就是完美的!
     */
    public Boolean isPerfact1() {
        Boolean tag = null;
        int x = Constant.X;
        int y = Constant.Y;
        for (int i = 0; i < x; i++) {
            for (int j = 0; j < y; j++) {
                Boolean value = oneWorld[i][j].getValue();
                if (value == null) {
                    continue;
                }
                tag = tag == null ? value : tag;
                if (tag != value) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 另一个判断图是否完美的方式,需要维护num和trueNum两个字段
     */
    public Boolean isPerfact() {
        return trueNum == 0 || trueNum == num ? true : false;
    }

    /**
     * 复制自身
     */
    public OneWorld copy() {
        Point[][] points = new Point[Constant.X][Constant.Y];
        for (int i = 0; i < Constant.X; i++) {
            for (int j = 0; j < Constant.Y; j++) {
                points[i][j] = oneWorld[i][j].copy();
            }
        }
        Point[] starts = new Point[Constant.NUMBER];
        for (int i = 0; i < Constant.NUMBER; i++) {
            starts[i] = start[i].copy();
        }

        OneWorld copyOne = new OneWorld();
        // copyOne.setOneWorld(points);
        // copyOne.setStart(starts);
        // copyOne.setNum(num);
        // copyOne.setTrueNum(trueNum);
        copyOne.oneWorld = points;
        copyOne.start = starts;
        copyOne.num = num;
        copyOne.trueNum = trueNum;
        return copyOne;
    }

    public Point[] getStart() {
        return start;
    }

    public Point[][] getOneWorld() {
        return oneWorld;
    }
}

OneStep.java

package world;

import java.util.ArrayList;
import java.util.List;

/**
 * 存储走一步之后的图;以及行走的步骤
 */
public class OneStep {
    private OneWorld oneWrold;
    // 步骤中为行走之前的值;steps为null,表示一步都没有走
    private List<Point>[] steps = new ArrayList[Constant.NUMBER];

    public OneStep(OneWorld oneWrold, List<Point>[] steps) {
        this.oneWrold = oneWrold;
        this.steps = steps;
    }

    public OneStep(OneWorld oneWrold) {
        super();
        this.oneWrold = oneWrold;
    }

    public OneWorld getOneWrold() {
        return oneWrold;
    }

    public void setOneWrold(OneWorld oneWrold) {
        this.oneWrold = oneWrold;
    }

    public List<Point>[] getSteps() {
        return steps;
    }

    public void setSteps(List<Point>[] steps) {
        this.steps = steps;
    }

    public List<Point>[] copySteps() {
        List<Point>[] lists = new ArrayList[Constant.NUMBER];
        for (int i = 0; i < Constant.NUMBER; i++) {
            List<Point> step = steps[i];
            if (step != null) {
                List<Point> list = new ArrayList<Point>();
                for (int j = 0; j < step.size(); j++) {
                    list.add(step.get(j).copy());
                }
                lists[i] = list;
            }
        }
        return lists;
    }

}

Constant.java

package world;

public class Constant {
    // 图中的行
    public static int X = 5;
    // 图中的列
    public static int Y = 4;
    // 图中的起点个数
    public static int NUMBER = 2;

}

Demo.java

package world;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;

public class Demo {
    private static Logger logger = Logger.getLogger(Demo.class);
    public static void main(String[] args) {

        // 初始化
        Point[][] oneWorld = new Point[Constant.X][Constant.Y];
        oneWorld[0] = new Point[] { new Point(null, 0, 0), new Point(false, 0, 1), new Point(true, 0, 2),new Point(null, 0, 3) };
        oneWorld[1] = new Point[] { new Point(false, 1, 0), new Point(false, 1, 1), new Point(true, 1, 2),new Point(false, 1, 3) };
        oneWorld[2] = new Point[] { new Point(true, 2, 0), new Point(true, 2, 1), new Point(false, 2, 2),new Point(null, 2, 3) };
        oneWorld[3] = new Point[] { new Point(false, 3, 0), new Point(true, 3, 1), new Point(true, 3, 2),new Point(true, 3, 3) };
        oneWorld[4] = new Point[] { new Point(null, 4, 0), new Point(true, 4, 1), new Point(true, 4, 2),new Point(null, 4, 3) };

        OneWorld world = new OneWorld(oneWorld, new Point(false, 1, 3), new Point(true, 3, 3));

        OneStep oneStep = new OneStep(world);
        Date begin = new Date();
        OneStep one = new Demo().run(oneStep);
        Date end = new Date();
        logger.info("**********************************************");
        logger.info(end.getTime() - begin.getTime());
        printsteps(one);
        logger.info("**********************************************");

    }
    public static void printsteps(OneStep one){
        if (one == null) {
            logger.info("没有结果!");
            return;
        }
        List<Point>[] steps = one.getSteps();
        for (int i = 0; i < Constant.NUMBER; i++) {
            List<Point> list = steps[i];
            StringBuffer sb=new StringBuffer();
            sb.append("第"+i+"步:");
            if (list == null) {
                continue;
            }
            for (Point p : list) {
                sb.append("(" + p.getX() + "," + p.getY() + ")   ");
            }
            logger.info(sb.toString());
        }

    }

    /**
     * 返回非null表示图是perfact,否则返回null;
     */
    public OneStep run(OneStep oneStep) {
        // 当图是perfact时,返回;
        if (oneStep.getOneWrold().isPerfact()) {
            return oneStep;
        }

        OneWorld oneWrold = oneStep.getOneWrold();
        List<Point>[] steps = oneStep.getSteps();

        // 当图中的某个步骤已经走完所有的点时,直接返回null;
        for (int i = 0; i < Constant.NUMBER; i++) {
            List<Point> step = steps[i];// 第i个起点行走的步骤
            if (step != null && step.size() == oneWrold.getNum()) {
                return null;
            }
        }
        List<OneStep> lists = new ArrayList<OneStep>();
        for (int i = 0; i < Constant.NUMBER; i++) {
            List<Point> step = steps[i];// 第i个起点行走的步骤
            // 上
            if (step == null) {
                // 没有走过,则先反转自身,在反转自身上一个点
                OneWorld up = oneWrold.copy();
                List<Point>[] upSteps = oneStep.copySteps();

                // 没有走过,则对应的步骤应该为null,声明步骤
                List<Point> upStep = new ArrayList<Point>();
                // 该步骤的起点;
                Point start = up.getStart()[i];

                // 反转起点
                Point p = up.getPointCopy(start.getX(), start.getY());
                upStep.add(p);
                up.ChangePoint(start.getX(), start.getY());
                // 反转上一个点
                if ((start.getX() - 1) >= 0) {
                    p = up.getPointCopy(start.getX() - 1, start.getY());
                    if (p.getValue() != null) {
                        upStep.add(p);
                        up.ChangePoint(start.getX() - 1, start.getY());
                        // 处理成功,添加到集合中
                        upSteps[i] = upStep;
                        lists.add(new OneStep(up, upSteps));
                    }
                }

            } else {
                OneWorld up = oneWrold.copy();
                List<Point>[] upSteps = oneStep.copySteps();

                List<Point> upStep = upSteps[i];
                Point start = upStep.get(upStep.size() - 1);
                // 反转上一个点
                if ((start.getX() - 1) >= 0) {
                    Point p = up.getPointCopy(start.getX() - 1, start.getY());
                    // 上一个点不能为null
                    if (p.getValue() != null) {
                        // 上一个点不能走过
                        int upStepLength = upStep.size();
                        int j = 0;
                        for (; j < upStepLength; j++) {
                            if (p.getX() == upStep.get(j).getX() && p.getY() == upStep.get(j).getY()) {
                                break;
                            }
                        }
                        if (j == upStepLength) {
                            upStep.add(p);
                            up.ChangePoint(start.getX() - 1, start.getY());
                            // 处理成功,添加到集合中
                            upSteps[i] = upStep;
                            lists.add(new OneStep(up, upSteps));
                        }
                    }
                }

            }
            // 下
            if (step == null) {
                // 没有走过,则先反转自身,在反转自身下一个点
                OneWorld down = oneWrold.copy();
                List<Point>[] downSteps = oneStep.copySteps();

                // 没有走过,则对应的步骤应该为null,声明步骤
                List<Point> downStep = new ArrayList<Point>();
                // 该步骤的起点;
                Point start = down.getStart()[i];

                // 反转起点
                Point p = down.getPointCopy(start.getX(), start.getY());
                downStep.add(p);
                down.ChangePoint(start.getX(), start.getY());

                // 反转下一个点
                if ((start.getX() + 1) < Constant.X) {
                    p = down.getPointCopy(start.getX() + 1, start.getY());
                    if (p.getValue() != null) {
                        downStep.add(p);
                        down.ChangePoint(start.getX() + 1, start.getY());
                        // 处理成功,添加到集合中
                        downSteps[i] = downStep;
                        lists.add(new OneStep(down, downSteps));
                    }
                }

            } else {
                OneWorld down = oneWrold.copy();
                List<Point>[] downSteps = oneStep.copySteps();

                List<Point> downStep = downSteps[i];
                Point start = downStep.get(downStep.size() - 1);
                // 反转下一个点
                if ((start.getX() + 1) < Constant.X) {
                    Point p = down.getPointCopy(start.getX() + 1, start.getY());
                    // 下一个点不能为null
                    if (p.getValue() != null) {
                        // 下一个点不能走过
                        int downStepLength = downStep.size();
                        int j = 0;
                        for (; j < downStepLength; j++) {
                            if (p.getX() == downStep.get(j).getX() && p.getY() == downStep.get(j).getY()) {
                                break;
                            }
                        }
                        if (j == downStepLength) {
                            downStep.add(p);
                            down.ChangePoint(start.getX() + 1, start.getY());
                            // 处理成功,添加到集合中
                            downSteps[i] = downStep;
                            lists.add(new OneStep(down, downSteps));
                        }
                    }
                }

            }
            // 左
            if (step == null) {
                // 没有走过,则先反转自身,在反转自身下一个点
                OneWorld left = oneWrold.copy();
                List<Point>[] leftSteps = oneStep.copySteps();

                // 没有走过,则对应的步骤应该为null,声明步骤
                List<Point> leftStep = new ArrayList<Point>();
                // 该步骤的起点;
                Point start = left.getStart()[i];

                // 反转起点
                Point p = left.getPointCopy(start.getX(), start.getY());
                leftStep.add(p);
                left.ChangePoint(start.getX(), start.getY());

                // 反转左侧一个点
                if ((start.getY() - 1) >= 0) {
                    p = left.getPointCopy(start.getX(), start.getY() - 1);
                    if (p.getValue() != null) {
                        leftStep.add(p);
                        left.ChangePoint(start.getX(), start.getY() - 1);
                        // 处理成功,添加到集合中
                        leftSteps[i] = leftStep;
                        lists.add(new OneStep(left, leftSteps));
                    }
                }

            } else {
                OneWorld left = oneWrold.copy();
                List<Point>[] leftSteps = oneStep.copySteps();

                List<Point> leftStep = leftSteps[i];
                Point start = leftStep.get(leftStep.size() - 1);
                // 反转左侧一个点
                if ((start.getY() - 1) >= 0) {
                    Point p = left.getPointCopy(start.getX(), start.getY() - 1);
                    // 下一个点不能为null
                    if (p.getValue() != null) {
                        // 下一个点不能走过
                        int leftStepLength = leftStep.size();
                        int j = 0;
                        for (; j < leftStepLength; j++) {
                            if (p.getX() == leftStep.get(j).getX() && p.getY() == leftStep.get(j).getY()) {
                                break;
                            }
                        }
                        if (j == leftStepLength) {
                            leftStep.add(p);
                            left.ChangePoint(start.getX(), start.getY() - 1);
                            // 处理成功,添加到集合中
                            leftSteps[i] = leftStep;
                            lists.add(new OneStep(left, leftSteps));
                        }
                    }
                }

            }
            // 右
            if (step == null) {
                // 没有走过,则先反转自身,在反转自身右侧的一个点
                OneWorld right = oneWrold.copy();
                List<Point>[] rightSteps = oneStep.copySteps();

                // 没有走过,则对应的步骤应该为null,声明步骤
                List<Point> rightStep = new ArrayList<Point>();
                // 该步骤的起点;
                Point start = right.getStart()[i];

                // 反转起点
                Point p = right.getPointCopy(start.getX(), start.getY());
                rightStep.add(p);
                right.ChangePoint(start.getX(), start.getY());

                // 反转右侧侧一个点
                if ((start.getY() + 1) < Constant.Y) {
                    p = right.getPointCopy(start.getX(), start.getY() + 1);
                    if (p.getValue() != null) {
                        rightStep.add(p);
                        right.ChangePoint(start.getX(), start.getY() + 1);
                        // 处理成功,添加到集合中
                        rightSteps[i] = rightStep;
                        lists.add(new OneStep(right, rightSteps));
                    }
                }

            } else {
                OneWorld right = oneWrold.copy();
                List<Point>[] rightSteps = oneStep.copySteps();

                List<Point> rightStep = rightSteps[i];
                Point start = rightStep.get(rightStep.size() - 1);
                // 反转右侧一个点
                if ((start.getY() + 1) < Constant.Y) {
                    Point p = right.getPointCopy(start.getX(), start.getY() + 1);
                    // 右一个点不能为null
                    if (p.getValue() != null) {
                        // 右一个点不能走过
                        int rightStepLength = rightStep.size();
                        int j = 0;
                        for (; j < rightStepLength; j++) {
                            if (p.getX() == rightStep.get(j).getX() && p.getY() == rightStep.get(j).getY()) {
                                break;
                            }
                        }
                        if (j == rightStepLength) {
                            rightStep.add(p);
                            right.ChangePoint(start.getX(), start.getY() + 1);
                            // 处理成功,添加到集合中
                            rightSteps[i] = rightStep;
                            lists.add(new OneStep(right, rightSteps));
                        }
                    }
                }

            }
        }
        // end
        for (OneStep one : lists) {
            OneStep temp = run(one);
            if (null != temp) {
                return temp;
            }
        }

        return null;
    }

}

优化思路:
1.对图进行预处理
2.优先处理步骤少的状态

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值