zoukankan      html  css  js  c++  java
  • 001 Phone Numbers

    解题思路:DF

    1002. Phone Numbers

    源代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
        class Program
        {
            //存放字母表
            private static Dictionary<char, int> m_WordsDic; 
            //int是每个word在callnumber中匹配的index位置,每个index对应的point可能是多个
            private static Dictionary<int,List<Point>> m_Wordspath;
            //将每个word转为digital
            private static List<Words> m_Digitals;
    
            private static Mark[] m_MinPath;
    
            static void Main(string[] args)
            {
                while (true)
                {
                    //初始化
                    Init();
                    string callNum;
                    int n;
                    //第一行是call number
                    callNum = Console.ReadLine();
                    if (callNum == "-1")
                        break;
                    //第二行是下面有多少word
                    n = int.Parse(Console.ReadLine());
                    //进行word存储
                    //word转化为数字
                    InitDigitalDic(n);
                    //生成wordPathDic
                    InitPathDic(callNum);
    
                    m_MinPath=new Mark[callNum.Length];
                    for (int i = 0; i < callNum.Length; i++)
                    {
                        m_MinPath[i]=new Mark();
                    }
                    InitPathMin(callNum.Length);
                    if (m_MinPath[callNum.Length-1].Num == 0)
                    {
                        //没有找到路径
                        Console.WriteLine("No solution.");
    
                    }
                    else
                    {
                        foreach (Point point in m_MinPath[callNum.Length-1].MarkPoints)
                        {
                            var markResult = new List<Point> {point};
                            if (OutPutResult(point, markResult, m_MinPath[callNum.Length - 1].Num))
                                break;
                        }
                    }
                }
                //Console.ReadLine();
            }
    
            private static bool OutPutResult(Point point,List<Point> mark,int count)
            {
                if (count == 1 && point.StartIndex != 0)
                {
                    //搜寻失败
                    return false;
                }
                //是否到达原点
                if(point.StartIndex==0)
                {
                    //换行,开始下一个最短解
                    OutPutMark(mark);
                    return true;
                }
                //如果没到达原点,那么继续往上回溯
                foreach (Point p in m_MinPath[point.StartIndex-1].MarkPoints)
                {
                    mark.Add(p);
                    if (OutPutResult(p, mark, (count - 1)))
                        return true;
                    mark.Remove(p);
                }
                return false;
            }
    
            private static void OutPutMark(List<Point> mark)
            {
                StringBuilder sb=new StringBuilder();
                for (var i = mark.Count-1; i >=0; i--)
                {
                    sb.Append(string.Format("{0} ", mark[i].Words.Letters));   
                }
                Console.WriteLine(sb.ToString(0, sb.Length - 1));
            }
    
            private static void InitPathMin(int n)
            {
                List<Point> StartList = null;
                if (m_Wordspath.TryGetValue(0, out StartList))
                {
                    //初始化第一点
                    foreach (Point point in StartList)
                    {
                        NextPoint(point, n);
                    }
                }
            }
            private static void AddMark(ref Mark mark,int num,Point point)
            {
                mark.Num = num;
                mark.MarkPoints.Add(point);
            }
            private static void NextPoint(Point prePoint,int n)
            {
                List<Point> list = null;
                int index = prePoint.EndIndex + 1;
                //开始对该点最小值进行对比生成
                if(!MinPoint(prePoint))
                    return;
                if (prePoint.EndIndex == n)
                {
                    //如果是终点,直接返回
                    return;
                }
                //如果dic这点无值,意味着死路
                if(!m_Wordspath.TryGetValue(index,out list))
                {
                    return;
                }
                //获得以该index作起始点的list
                foreach (Point point in list)
                {
                    //开始层的搜寻
                    NextPoint(point, n);
                }
            }
            private static bool MinPoint(Point point)
            {
                var mark = m_MinPath[point.EndIndex];
                int temp = 1;
                //如果是第一点
                if (point.StartIndex - 1 >= 0)
                    temp = m_MinPath[point.StartIndex - 1].Num + 1;
                if (mark.Num == 0)
                {
                    //如果未初始化,直接赋值
                    AddMark(ref mark, temp, point);
                    return true;
                }
                if(temp<mark.Num)
                {
                    mark.MarkPoints.Clear();
                    AddMark(ref mark, temp, point);
                    return true;
                }
                if (temp == mark.Num)
                {
                    if (!NotContains(mark, point))
                    {
                        AddMark(ref mark, temp, point);
                        return false;
                    }
                }
                return false;
            }
    
            private static bool NotContains(Mark mark, Point point)
            {
                return mark.MarkPoints.Any(r => r.StartIndex == point.StartIndex && r.EndIndex == point.EndIndex&&r.Words.Letters==point.Words.Letters);
            }
    
            private static void InitPathDic(string callNum)
            {
                foreach (Words mDigital in m_Digitals)
                {
                    FindNextIndex(0,callNum, mDigital);
                }
            }
            private static void FindNextIndex(int startIndex,string lest,Words words)
            {
                //如果未找到,那么就返回
                int index = lest.IndexOf(words.Digital);
                if (index == -1)
                    return;
                int endIndex = index + words.Digital.Length - 1;
                AddPoint(index + startIndex, endIndex + startIndex, words);
                FindNextIndex(index + 1 + startIndex, lest.Substring(index + 1), words);
                //index += startIndex;
                ////如果找到了,添加point,用剩下的stirng继续找匹配
                //int lastIndex = index + words.Digital.Length;
                //AddPoint(index, lastIndex, words);
                //FindNextIndex(startIndex + 1, lest.Substring(1), words);
            }
            private static void AddPoint(int startIndex,int lastIndex,Words words)
            {
                List<Point> temp = null;
                if(m_Wordspath.TryGetValue(startIndex,out temp))
                {
                    //如果已经存在该项,那么不做添加
                    if (!temp.Any(r => r.StartIndex == startIndex && r.EndIndex == lastIndex && r.Words == words))
                        temp.Add(new Point(startIndex, lastIndex, words));
                }
                else
                {
                    m_Wordspath[startIndex] = new List<Point>() { new Point(startIndex, lastIndex, words) };  
                }
            }
            private static void InitDigitalDic(int n)
            {
                for (int i = 0; i < n; i++)
                {
                    string lineValue = Console.ReadLine();
                    var sb = new StringBuilder();
                    foreach (char c in lineValue)
                    {
                        sb.Append(m_WordsDic[c]);
                    }
                    m_Digitals.Add(new Words(sb.ToString(), lineValue));
                }
            }
    
            private static void Init()
            {
                m_Digitals = new List<Words>();
                m_WordsDic = new Dictionary<char, int>()
                                 {
                                     {'i', 1},
                                     {'j', 1},
                                     {'a', 2},
                                     {'b', 2},
                                     {'c', 2},
                                     {'d', 3},
                                     {'e', 3},
                                     {'f', 3},
                                     {'g', 4},
                                     {'h', 4},
                                     {'k', 5},
                                     {'l', 5},
                                     {'m', 6},
                                     {'n', 6},
                                     {'p', 7},
                                     {'r', 7},
                                     {'s', 7},
                                     {'t', 8},
                                     {'u', 8},
                                     {'v', 8},
                                     {'w', 9},
                                     {'x', 9},
                                     {'y', 9},
                                     {'o', 0},
                                     {'q', 0},
                                     {'z', 0},
                                 };
                m_Wordspath = new Dictionary<int, List<Point>>();
            }
        }
    
        class  Point
        {
            public int StartIndex;
            public int EndIndex;
            public Words Words;
    
            public Point(int startIndex,int endIndex,Words letters)
            {
                StartIndex = startIndex;
                EndIndex = endIndex;
                Words = letters;
            }
        }
    
        class Words
        {
            public string Digital;
            public string Letters;
            public Words(string digital,string letter)
            {
                Digital = digital;
                Letters = letter;
            }
        }
    
        class Mark
        {
            public int Num;
            public List<Point> MarkPoints;
    
            public Mark()
            {
                MarkPoints = new List<Point>();
            }
        }
    

      

  • 相关阅读:
    sqlite设置主键
    sqlite 分页
    Server.Transfer方法在页面间传值
    JS实现背景透明度可变,文字不透明的效果
    css hack 区分浏览器
    Asp.net(c#)实现多线程断点续传
    C# 中的委托和事件
    使用C#的HttpWebRequest访问网站
    相似图片搜索的原理
    asp.net内存溢出问题
  • 原文地址:https://www.cnblogs.com/suriyel/p/2795470.html
Copyright © 2011-2022 走看看