图灵社区迷宫题

http://www.ituring.com.cn/article/16537 题目地址~

随手写个双向广搜


   

        private class Pos
        {
            internal enum Direction
            {
                Forward,
                Backwrad,
            }

            public Direction Dirct { get; set; }
            public int CurrentValue { get; set; }
            public int PosIndex { get; set; }
            public Pos LastPos { get; set; }
            public Operation Opt { get; set; }

            internal class Operation
            {
                public Func<int, int> Opt { get; set; }
                public string Desc { get; set; }
                public Operation Opposite { get; set; }
            }


            private static readonly Operation ForwardOptA = new Operation { Opt = i => i / 2, Desc = "/ 2", };
            private static readonly Operation ForwardOptB = new Operation { Opt = i => i + 7, Desc = "+ 7", };
            private static readonly Operation ForwardOptC = new Operation { Opt = i => i * 3, Desc = "* 3", };
            private static readonly Operation ForwardOptD = new Operation { Opt = i => i - 5, Desc = "- 5", };
            private static readonly Operation BackwardOptA = new Operation { Opt = i => i * 2, Desc = "* 2", };
            private static readonly Operation BackwardOptB = new Operation { Opt = i => i - 7, Desc = "- 7", };
            private static readonly Operation BackwardOptC = new Operation { Opt = i => i / 3, Desc = "/ 3", };
            private static readonly Operation BackwardOptD = new Operation { Opt = i => i + 5, Desc = "+ 5", };
            static Pos()
            {
                ForwardOptA.Opposite = BackwardOptA;
                ForwardOptB.Opposite = BackwardOptB;
                ForwardOptC.Opposite = BackwardOptC;
                ForwardOptD.Opposite = BackwardOptD;
                BackwardOptA.Opposite = ForwardOptA;
                BackwardOptB.Opposite = ForwardOptB;
                BackwardOptC.Opposite = ForwardOptC;
                BackwardOptD.Opposite = ForwardOptD;
            }


            public IEnumerable<Pos> GetNextLevelPos()
            {
                var result = new List<Pos>();
                switch (Dirct)
                {
                    case Direction.Forward:
                        switch (PosIndex)
                        {
                            case 1:
                                NewPos(result, this, ForwardOptA, 2);
                                NewPos(result, this, ForwardOptB, 2);
                                break;
                            case 2:
                                NewPos(result, this, ForwardOptA, 1);
                                NewPos(result, this, ForwardOptB, 1);
                                NewPos(result, this, ForwardOptC, 3);
                                NewPos(result, this, ForwardOptD, 3);
                                break;
                            case 3:
                                NewPos(result, this, ForwardOptC, 2);
                                NewPos(result, this, ForwardOptD, 2);
                                break;
                        }
                        break;
                    case Direction.Backwrad:
                        switch (PosIndex)
                        {
                            case 3:
                                if (CurrentValue % 3 == 0)
                                {
                                    NewPos(result, this, BackwardOptC, 2);
                                }
                                NewPos(result, this, BackwardOptD, 2);
                                break;
                            case 2:
                                if (CurrentValue % 3 == 0)
                                {
                                    NewPos(result, this, BackwardOptC, 3);
                                }
                                NewPos(result, this, BackwardOptD, 3);
                                NewPos(result, this, BackwardOptA, 1);
                                NewPos(result, this, BackwardOptB, 1);
                                break;
                            case 1:
                                NewPos(result, this, BackwardOptA, 2);
                                NewPos(result, this, BackwardOptB, 2);
                                break;
                        }
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
                return result;
            }

            private void NewPos(List<Pos> result, Pos lastPos, Operation opt, int nextIndex)
            {
                if (lastPos.Opt != opt)
                    result.Add(new Pos { Opt = opt, CurrentValue = opt.Opt(lastPos.CurrentValue), Dirct = lastPos.Dirct, LastPos = lastPos, PosIndex = nextIndex });
            }
        }

        private static void Main(string[] args)
        {
            var noneOpt = new Pos.Operation { Desc = "none" };
            noneOpt.Opposite = noneOpt;
            var first = new Pos { CurrentValue = 2011, Dirct = Pos.Direction.Forward, LastPos = null, PosIndex = 1, Opt = noneOpt };
            var last = new Pos { CurrentValue = 2012, Dirct = Pos.Direction.Backwrad, LastPos = null, PosIndex = 3, Opt = noneOpt };

            var level = 1;
            var lastForwadList = new List<Pos>() { first };
            var lastBackwadList = new List<Pos>() { last };
            while (true)
            {
                if (level > 100000)
                {
                    Console.WriteLine("no result");
                    break;
                }
                var forward = new List<Pos>();
                var backward = new List<Pos>();
                foreach (var pose in lastForwadList)
                {
                    forward.AddRange(pose.GetNextLevelPos());
                }

                foreach (var pose in lastBackwadList)
                {
                    backward.AddRange(pose.GetNextLevelPos());
                }

                var x = from f in forward from b in backward where f.Opt.Opposite != b.Opt && f.CurrentValue == b.CurrentValue && f.PosIndex == b.PosIndex select new { f, b };
                var result = x.FirstOrDefault();
                if (result != null)
                {
                    ShowResult(result.f, result.b);
                    break;
                }
                lastForwadList = forward;
                lastBackwadList = backward;
                level++;
            }
        }

        private static void ShowResult(Pos f, Pos b)
        {
            ShowForward(f);
            ShowBackward(b);
        }

        private static void ShowBackward(Pos pos)
        {
            Console.WriteLine("位置{0},当前值{1},执行操作{2}", pos.PosIndex, pos.CurrentValue, pos.Opt.Opposite.Desc);
            if (pos.LastPos != null)
            {
                ShowBackward(pos.LastPos);
            }
        }

        private static void ShowForward(Pos pos)
        {
            if (pos.LastPos != null)
            {
                ShowForward(pos.LastPos);
            }
            Console.WriteLine("执行操作{2},到达位置{0},当前值{1}", pos.PosIndex, pos.CurrentValue, pos.Opt.Desc);
        }


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值