一道简单的ACM题目解决办法

一道简单的ACM题目

  TOM 设计了一个可以前进或后退的机器人,该机器人在每个位置i会得到一个移动步数的指令Ki(i=1,2……N)
聪明的机器人判断是应该前进Ki步还是倒退Ki步
  例如给定指令序列(3 3 1 2 5),表示机器人在第一个位置时可以前进3个位置到第4个位置,此时不可以倒退,因为倒退就越界了(1-3=-2)在第2个位置可以前进3个位置,此时还不可以倒退,在第3个位置上可以前进1个位置到第4个位置,或者后退1个位置到第2个位置……
  问:对于给定的序列指(x1,x2,x3……)和A B两个位置,机器人从A到B,至少要判断几次?
  要求:
  输入:
  第一行:M 表示下面要测试的数据组数。
  接下来每组两行数据
  头一行N A B(n表示指令数,1<N<50,1<=A,B<=N)
  下一行:k1,k2,k3……kn(0<ki<=N)
  输出:机器人从A到B至少要判断的次数,若走不到B输出-1;

样例:5 1 2
  3 3 1 2 5
  8 5 3
  1 2 1 5 3 1 1 1
  输出 3
  -1

------解决方案--------------------
探讨
不就裸的最短路么

------解决方案--------------------
先对每个结点建立一个入度表(最好用hash表做)。取B点作为初始当前集合,同时删除掉B的出度(最多两个)。
<loop>取出当前集合的所有入度表做为当前集合,同时删除当前集合的所有出度。当前集合长度为0或A在其中则结束,否则循环。</loop>
------解决方案--------------------
C# code
        public static int minJump(int[] jump, int start, int end)
        {
            //如果确定长度小于50,用位图替代HashSet,应该能提升几倍的效率
            int value = -1;
            if (jump != null)
            {
                int length = jump.Length;
                if (length != 0 && --start >= 0 && --end >= 0 && start < length && end < length)
                {
                    value = 0;
                    if (start != end)
                    {
                        #region 建立入度表
                        int left, right;
                        HashSet<int>[] jumpIn = new HashSet<int>[length];
                        for (int index = length - 1; index >= 0; index--)
                        {
                            if (index != end)
                            {
                                if ((right = (index << 1) - (left = index - jump[index])) < length)
                                {
                                    if (jumpIn[right] == null) jumpIn[right] = new HashSet<int>();
                                    jumpIn[right].Add(index);
                                }
                                if (left >= 0)
                                {
                                    if (jumpIn[left] == null) jumpIn[left] = new HashSet<int>();
                                    jumpIn[left].Add(index);
                                }
                            }
                        }
                        #endregion

                        if (jumpIn[end] == null) value--;
                        else
                        {
                            value++;
                            if (!jumpIn[end].Contains(start))
                            {
                                #region 初始化 当前集合
                                HashSet<int> currentIndex = new HashSet<int>();
                                foreach (int nextIndex in jumpIn[end])
                                {
                                    if (jumpIn[nextIndex] != null)
                                    {
                                        currentIndex.Add(nextIndex);
                                        if ((right = (nextIndex << 1) - (left = nextIndex - jump[nextIndex])) < length && right != end)
                                        {
                                            if (jumpIn[right].Count == 1) jumpIn[right] = null;
                                            else jumpIn[right].Remove(nextIndex);
                                        }
                                        if (left >= 0 && left != end)
                                        {
                                            if (jumpIn[left].Count == 1) jumpIn[left] = null;
                                            else jumpIn[left].Remove(nextIndex);
                                        }
                                    }
                                }
                                #endregion

                                if (currentIndex.Count == 0) value = -1;
                                else
                                {
                                    for (HashSet<int> nextIndexs; value != -1; currentIndex = nextIndexs)
                                    {
                                        #region 取出当前集合的所有入度表做为当前集合
                                        nextIndexs = new HashSet<int>();
                                        foreach (int index in currentIndex)
                                        {
                                            if (jumpIn[index] != null)
                                            {
                                                if (jumpIn[index].Contains(start))
                                                {
                                                    nextIndexs.Add(start);
                                                    break;
                                                }
                                                else
                                                {
                                                    foreach (int nextIndex in jumpIn[index])
                                                    {
                                                        if (jumpIn[nextIndex] != null)
                                                        {
                                                            nextIndexs.Add(nextIndex);
                                                            if ((right = (nextIndex << 1) - (left = nextIndex - jump[nextIndex])) < length && right != index)
                                                            {
                                                                if (jumpIn[right].Count == 1) jumpIn[right] = null;
                                                                else jumpIn[right].Remove(nextIndex);
                                                            }
                                                            if (left >= 0 && left != index)
                                                            {
                                                                if (jumpIn[left].Count == 1) jumpIn[left] = null;
                                                                else jumpIn[left].Remove(nextIndex);
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                        #endregion
                                        if (nextIndexs.Count == 0) value = -1;
                                        else
                                        {
                                            value++;
                                            if (nextIndexs.Contains(start)) break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return value;
        }