一道小学题目

偶尔看到的,题目大致如下:

有一个数,abcdefghi,每个字母分别代表了1到9之间的数字(数字不重复),而且该数有一个特性,a能被1整除,ab能被2整除,...abcdefghi能被9整除,求该数。

反正我是不知道小学方法该怎么求,看到这题目,第一反应就是,循环一下就好了——确实最简单的方法,不过要写的循环太多,也容易出错。

再一分析,这不是个递归的过程么,即该数能被本身长度所整除。试了一下,果然出结果了。

代码如下,为了写起来方便,加了两个扩展方法。

namespace ConsoleApplication1
{
    static class Program
    {
        static int total = 0;//看看递归了多少次
        const int LENGTH_OF_NUMBER = 9;

        static void Main(string[] args)
        {
            string[] list = new string[] { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
            Console.WriteLine("结果是:{0},共运算:{1}次",GetNumber("",list),total);
            Console.ReadKey();
        }

        /// <summary>
        /// 递归取得正确的数
        /// </summary>
        /// <param name="str">当前的字符串</param>
        /// <param name="list">剩余可用的字符列表</param>
        /// <returns>错误返回空字符串,无错但是可以继续,则返回下一个字符,成功则返回结果</returns>
        static string GetNumber(string str, IEnumerable<string> list)
        {
            total++;
            if (str.Length > 0)
            {
                //如果当前条件都不满足,后续的就没必要继续了
                if (!str.CanDivBy(str.Length))
                    return "";
                else if (str.Length == LENGTH_OF_NUMBER) //得到符合的数了,也就没必要继续了
                    return str;
            }
            
            foreach (var v in list)
            {
                string tmp = GetNumber(str + v, list.NewList(v));

                if (tmp.Length != LENGTH_OF_NUMBER)
                    continue;
                else
                {
                    return tmp;
                }
            }
            return "";
        }

        /// <summary>
        /// 是否能被某个整数整除
        /// </summary>
        /// <param name="val_str"></param>
        /// <param name="div"></param>
        /// <returns>是否可以被整除</returns>
        public static bool CanDivBy(this string val_str, int div)
        {
            long val;
            if (!long.TryParse(val_str, out val))
                return false;
            return (val * 1.0 / div - val / div) == 0;
        }

        /// <summary>
        /// 根据当前列表,生成一个不包含指定数的新列表
        /// </summary>
        /// <param name="old_list"></param>
        /// <param name="val"></param>
        /// <returns></returns>
        public static IEnumerable<string> NewList(this IEnumerable<string> old_list, string val)
        {
            int v = int.Parse(val);
            return from a in old_list where int.Parse(a) != v select a;
        }

    }
}

  

结果是:381654729,共运算:523次

比我想像的次数少一些。

请无视代码中混乱的命名,纯粹一时兴起验证一下。

题目还可以改一下,即可以加上0,变成abcdefghij可以被10整除,只要把长度改成10,数组里加个0就好了

原文地址:https://www.cnblogs.com/varlxj/p/3214401.html