您的位置:首页 > 编程语言 > C#

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

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

先看看题目:

最小操作数
返回首页

发布公司:
有 效 期:
赛 区:

ThoughtWorks
2013-06-26至2014-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",有以下两种可能:

"hit" -> "hot" -> "dot" -> "dog" -> "cog";
"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;

代码写的有些啰嗦,未做整理。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: