using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{
/*
     *
     * 腾讯算法面试题 算法与代码
     *   题目是这样的:给你10分钟时间,根据上排给出十个数,
     * 在其下排填出对应的十个数。
     * 要求下排每个数都是先前上排对应那个数在下排十个数中出现的次数。
    例如:
        上排的十个数如下:
        0  1  2  3  4  5  6  7  8  9 ,那么下排的数应该是
     *  6  2  1  0  0  0  1  0  0  0
     *
     * 其实这是有规律可循的:
     * 不仅0~9有唯一解,0~n都只有唯一解。关键是最后面一个1它可以左右移动,1和2下面的数永远是2和1,
     * 0下面对应的数为n-3(n>=3),上排数n-3下面对应的数为1,其它上排数下面对应为0就ok了。
     * 有了这个一般性的结论再大的数都可以马上给出答案。
     *
     * 但是如果不是连续的数呢??例如 5 10 50 24 11 ,上面的方法就不好使了吧?
     * 下面的方法就是万能的方法了,不论给出的数字是否连续,都可以用
     */

    class Test
    {
        int[] top;
        public int[] Top
        {
            get { return top; }
            set { top = value; }
        }
        int[] bottom;
        public int[] Bottom
        {
            get { return bottom; }
            set { bottom = value; }
        }
        bool flag = false;
        public bool Flag
        {
            get { return flag; }
            set { flag = value; }
        }
        int length;
        public int Length
        {
            get { return length; }
            set { length = value; }
        }
        public Test(int length)
        {
            this.Length = length<4?4:length;
            Top = new int[Length];
            Bottom = new int[Length];
        }
        public static void Main()
        {
            /*测试1*/
            Console.WriteLine("测试1");
            Test t1 = new Test(20);
            t1.Inital();
            //如果Top的长度小于4,不可能实现,除非不是从0开始的连续数!
            t1.SetBottom();
            t1.Print(t1.Top);
            t1.Print(t1.Bottom);
 
            /*测试2
             *
             * 当Top不是从0开始的连续的数字时候,结果可能不止一种!
             */
            Console.WriteLine("测试2");
            Test t2 = new Test(10);
            t2.Top = new int[] { 0, 5, 12, 10, 6, 11, 2, 8, 4, 7 };
            for (int j = 0; j < 20; j++)
            {
                //每次循环确保Flag为false;
                t2.Flag = false;
                for (int i = 0; i < t2.Bottom.Length; i++)
                {
                    t2.Bottom[i] = j;
                }
                t2.SetBottom();
                Console.WriteLine(j + "::");
                t2.Print(t2.Top);
                t2.Print(t2.Bottom);
                Console.WriteLine();
            }
        }
 

        void Inital()
        {
            for (int i = 0; i < Top.Length; i++)
            {
                Top[i] = i;
            }
        }
        void SetBottom()
        {
            while (!Flag)
            {
                //循环逐一对Bottom赋值,直到Bottom中没有数值变动为止!
                SetNextBottom();
            }
        }
        //对Bottom逐一赋值!
        void SetNextBottom()
        {
            int a;
            bool temp = true;
            for (int i = 0; i < Bottom.Length; i++)
            {
                a = GetSum(Top[i]);
                if (Bottom[i] != a)
                {
                    Bottom[i] = a;
                    temp = false;
                }
            }
            Flag = temp;
        }
        //Bottom中出现num的次数!
        int GetSum(int num)
        {
            int count = 0;
            for (int i = 0; i < Bottom.Length; i++)
            {
                if (Bottom[i] == num)
                {
                    count++;
                }
            }
            return count;
        }
        //数字输出方法,1位数与2位数!
        string ReturnNumber(int num)
        {
            string s = "" + num;
            if (s.Length == 1)
            {
                return " " + s + "," + "  ";
            }
            else if (s.Length == 2)
            {
                return s.Substring(0, 1) + " " + s.Substring(1, 1) + ", ";
            }
            return "  ";
        }
        //输出数组!
        void Print(int[] a)
        {
            for (int i = 0; i < a.Length; i++)
            {
                Console.Write(ReturnNumber(a[i]));
            }
            Console.WriteLine();
        }

    }
}