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);
}