最小操作数-c#求解-英雄会在线编程题目

来源:互联网 发布:snip软件下载 编辑:程序博客网 时间:2024/06/10 07:51

    有几天没上来写编程挑战赛的解法了,主要是新出的c#提交都有问题,所以,只好做做之前发布的题,看了下这道题,最小操作数还没有,就做这道题吧。

先看看题目:

最小操作数

返回首页

  • 发布公司:
  • 有 效 期:
  • 赛 区:
  • ThoughtWorks
  • 2013-06-262014-03-23
  • 北京
  • 难 度 等 级:
  • 答 题 时 长:
  • 编程语言要求:
  • 120分钟
  • C++ Java C#                
题目详情

给了A、B两个单词和一个单词集合Dict,每个的长度都相同。我们希望通过若干次操作把单词A变成单词B,每次操作可以改变单词中的一个字母,同时,新产生的单词必须是在给定的单词集合Dict中。求所有行得通步数最少的修改方法。


   举个例子如下:

Given:

   A = "hit"

   B = "cog"

   Dict = ["hot","dot","dog","lot","log"]

Return

[

   ["hit","hot","dot","dog","cog"],

   ["hit","hot","lot","log","cog"]

]


    即把字符串A = "hit"转变成字符串B = "cog",有以下两种可能:

  1. "hit" -> "hot" ->  "dot" ->  "dog" -> "cog";
  2. "hit" ->  "hot" ->  "lot" ->  "log"  ->"cog"。

 

 

      这道题一看完,就觉得不算难,感觉有很多种做法,如果把每个单词当做一个点来看,就是从A点到B点的走法,要求路径最短,很像是走迷宫,呵呵,所以,就直接用A*寻径算法,其实就是动态规划算法。

      既然确定了算法方向,那么就考虑具体怎么算吧。

1、首先我们要考虑评估因子,这里很容易就知道,评估因子就是路径步骤,从A到B要经过多少步。

2、需要用到几个集合来存储这些数据:A可以到达的单词集合ADic,能够直接到达B的单词集合BDic,已经走过的单词集合usedDic,还没有走过的单词集合unUsedDic,每个单词能够达到其他单词的集合Dic。

      解题思路:

1、首先从A开始,吧能够达到的单词放入unUsedDic,评估因子为1.

2、然后查找评估因子为1的节点,看看此节点能否直接到达B,不能,则将能够到达的单词节点添加到unUsedDic中去,评估因子为2,并将因子为1的节点移入到useDic中去,注意,在添加节点时,要判断此节点是否在unUsedDic或者usedDic中存在过,如果存在,说明之前已经走过。不用添加,走回头路。

3、评估因子为1的全部走完后,如果没有找到,那就寻找评估因子为2的,重复步骤2,直到评估因子为K时找到为止,然后遍历评估因子为K的所有可能,找出所有可能,完成结束。

      思路就是这样的,按照思路写完后提交,ok没有问题。

代码部分:

首先是几个静态的集合变量:

static Dictionary<string, string> usedDic = new Dictionary<string, string>();
        static Dictionary<string, List<string>> DictKey = new Dictionary<string, List<string>>();
        static Dictionary<string, string> unuseDic = new Dictionary<string, string>();
        static Dictionary<string, int> BDic = new Dictionary<string, int>();
        static List<string> PathString;

 

查找函数:

public static void find(int value,bool finded)
        {
            string path = "";
            string key = "";
            foreach (KeyValuePair<string, string> kvp in unuseDic)
            {
                if (kvp.Value.Split(',').Length  == value)
                {
                    key = kvp.Key;
                    path = kvp.Value;
                    break;
                }
            }
            if (key != "")
            {
                usedDic.Add(key,unuseDic[key]);  
                unuseDic.Remove(key);
                bool flag = cal(key, usedDic[key]);
                if (flag)
                {
                    PathString.Add(path + "," + key);
                    find(value, flag);
                }
                else
                {
                    find(value, finded);
                }
            }
            else
            {
                //当前的找完了,找下一步的
                if (finded)
                {
                    //最短的找到了,并且找完了,不用进一步寻找了
                }
                else
                {
                    //没找到,需要进一步寻找
                    if (unuseDic.Count > 0)
                    {
                        find(value + 1, finded);
                    }
                }
            }
        }

处理节点函数,

 public static bool cal(string key,string path)
        {
            bool flag = false;
            if (BDic.ContainsKey(key))
            {
                flag = true;
            }
            else
            {
                List<string> list = DictKey[key];
                for (int i = 0; i < list.Count; i++)
                {
                    if (unuseDic.ContainsKey(list[i]) || usedDic.ContainsKey(list[i]))
                    {
                        continue;
                    }
                    else
                    {
                        unuseDic.Add(list[i], path+","+key);
                    }
                }
            }
            return flag;
        }

主函数中的处理过程:

usedDic = new Dictionary<string, string>();
            DictKey = new Dictionary<string, List<string>>();
            unuseDic = new Dictionary<string, string>();
            BDic = new Dictionary<string, int>();
            PathString = new List<string>();
            List<string> ADic = new List<string>();

            string A = start;
            string B = end;
            string[] Dict = dict;
           
            if(A==B)
            {
                string[][] r = new string[0][];
                //r[0]=new string[0];
                return r;
            }
            for (int i = 0; i < A.Length; i++)
            {
                if (A.Remove(i, 1) == B.Remove(i, 1))
                {
                    PathString.Add(A + "," + B);
                   
                    break;
                }
            }
            if (PathString.Count >0)
            {
                string[][] r = new string[PathString.Count][];
                string[] path = PathString[0].Split(',');
                r[0] = path;
                return r;
            }
           
           
            #region 初始化字典关联数据
            for (int i = 0; i < Dict.Length; i++)
            {
                List<string> values = new List<string>();
                for (int j = 0; j < Dict.Length; j++)
                {
                    if (i == j)
                    {
                        continue;
                    }
                    for (int k = 0; k < Dict[i].Length; k++)
                    {
                        if (Dict[i].Remove(k, 1) == Dict[j].Remove(k, 1))
                        {
                            values.Add(Dict[j]);
                            break;
                        }
                    }
                }
                DictKey.Add(Dict[i], values);
            }
            #endregion
            #region 初始化A能够变化为哪些dic,B是由哪些dic变来的
            for (int i = 0; i < Dict.Length; i++)
            {
                for (int j = 0; j < A.Length; j++)
                {
                    if (Dict[i].Remove(j, 1) == A.Remove(j, 1))
                    {
                        ADic.Add(Dict[i]);
                        unuseDic.Add(Dict[i], A);
                        break;
                    }
                }
                for (int j = 0; j < A.Length; j++)
                {
                    if (Dict[i].Remove(j, 1) == B.Remove(j, 1))
                    {
                        BDic.Add(Dict[i], 1);
                        break;
                    }
                }
            }
            #endregion
            find(1, false);
            for (int i = 0; i < PathString.Count; i++)
            {
                PathString[i] += "," + B;
            }
            string[][] result = new string[PathString.Count][];
            for (int i = 0; i < PathString.Count; i++)
            {
                result[i] = PathString[i].Split(',');
            }
            return result;

    代码写的有些啰嗦,未做整理。

0 0
原创粉丝点击