using System.Collections.Generic; using System.Linq; void Main() { List blocks = new List() { "bo", "xk", "dq", "cp", "na", "gt", "re", "tg", "qd", "fs", "jw", "hu", "vi", "an", "ob", "er", "fs", "ly", "pc", "zm" }; List words = new List() { "A", "BARK", "BOOK", "TREAT", "COMMON", "SQUAD", "CONFUSE"}; var solver = new ABC(blocks); foreach( var word in words) { Console.WriteLine("{0} :{1}", word, solver.CanMake(word)); } } class ABC { readonly Dictionary> _blockDict = new Dictionary>(); bool[] _used; int _nextBlock; readonly List _blocks; private void AddBlockChar(char c) { if (!_blockDict.ContainsKey(c)) { _blockDict[c] = new List(); } _blockDict[c].Add(_nextBlock); } private void AddBlock(string block) { AddBlockChar(block[0]); AddBlockChar(block[1]); _nextBlock++; } public ABC(List blocks) { _blocks = blocks; foreach (var block in blocks) { AddBlock(block); } } public bool CanMake(string word) { word = word.ToLower(); if (word.Length > _blockDict.Count) { return false; } _used = new bool[_blocks.Count]; return TryMake(word); } public bool TryMake(string word) { if (word == string.Empty) { return true; } var blocks = _blockDict[word[0]].Where(b => !_used[b]); foreach (var block in blocks) { _used[block] = true; if (TryMake(word.Substring(1))) { return true; } _used[block] = false; } return false; } }