亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

利用編程解決一道數學題

2019-11-14 13:56:13
字體:
來源:轉載
供稿:網友

問題

在朋友QQ空間看到一道題,如下:

psb

當時順手畫了條數軸,在數軸上標出了各個算式的解的特點:和為7的算式的解關于4對稱,和為9的解關于5對稱等等。草草算了下,發現很難同時滿足5個條件。而細算又太麻煩,算了,反正是程序員,寫程序求解吧。

利用笛卡爾積求解

因為是4個算式,很自然的就想到窮舉法。將每個算式可能的結果放在一起算笛卡爾積,如果有解的話,則必然存在一個笛卡爾積里面存在1到8這8個不同的元素。

計算笛卡爾積的代碼如下:

/// <summary>/// 計算元素集列表的笛卡爾積/// </summary>/// <typeparam name="T">元素具體類型</typeparam>/// <param name="sets">元素集列表</param>/// <returns>笛卡爾積列表</returns>public static T[][] CalculateCartesianPRoduct<T>(this IList<IList<T>> sets){    // 笛卡爾積總數    int total = 1;    // 元素集個數    int setCount = 0;    foreach (var set in sets)    {        total *= set.Count;        setCount++;    }    // 笛卡爾積列表    var products = new T[total][];    // 除數列表,用于計算每個笛卡爾積的情況    var dividers = new int[setCount];    int divider = 1;    // 倒序循環,因為后面的多種情況對應前面的一種情況    for (int counter = setCount - 1; counter >= 0; counter--)    {        dividers[counter] = divider;        divider *= sets[counter].Count;    }    // 計算笛卡爾積,共有permutationNumber個笛卡爾積,    // 從0到permutationNumber中,每個數字對應一種笛卡爾積情況    for (int counter = 0; counter < total; counter++)    {        // 一個笛卡爾積的情況        var permutation = new T[setCount];        int index = 0;        foreach (var set in sets)        {            // 將數字映射到元素集中的位置            var pos = (counter / dividers[index]) % set.Count;            permutation[index] = set[pos];            index++;        }        products[counter] = permutation;    }    return products;}

原理是將笛卡爾積解的總個數里的每個數字映射到一個解。

比如前面幾個笛卡爾積如下:

[2, 1] [3, 1] [1, 6] [1, 8]
[2, 1] [3, 1] [1, 6] [2, 7]
[2, 1] [3, 1] [1, 6] [3, 6]
[2, 1] [3, 1] [1, 6] [4, 5]
[2, 1] [3, 1] [2, 5] [1, 8]
[2, 1] [3, 1] [2, 5] [2, 7]
[2, 1] [3, 1] [2, 5] [3, 6]
[2, 1] [3, 1] [2, 5] [4, 5]

全排列

后面我又想到,實際上計算全排列也可以解決此題。將1到8取全排列,如果此題有解的話,則必然存在一個全排列,使得每兩個元素為一對,依次滿足4個算式。

簡單粗暴的解法

代碼如下:

/// <summary>/// 計算指定元素集的全排列/// </summary>/// <typeparam name="T">元素的具體類型</typeparam>/// <param name="collection">元素集</param>/// <returns>全排列</returns>public static IEnumerable<T[]> CalculatePermutationCrude<T>(ICollection<T> collection){    // 元素個數    int elementCount = collection.Count();    // 全排列列表    var permutations = new List<T[]>();    // 一個全排列    var permutation = new List<T>();    CalculatePermutationCrude(permutations, permutation, collection, elementCount);    return permutations;}/// <summary>/// 計算指定元素集的全排列/// </summary>/// <typeparam name="T">元素的具體類型</typeparam>/// <param name="permutations">全排列列表</param>/// <param name="permutation">一個全排列</param>/// <param name="collection">元素集</param>/// <param name="setLength">集合長度</param>private static void CalculatePermutationCrude<T>(    List<T[]> permutations,    List<T> permutation,    ICollection<T> collection,    int setLength){    if (permutation.Count < setLength)    {        foreach (var item in collection)        {            // 不是可重排列,不能包含            if (!permutation.Contains(item))            {                var temp = permutation.ToList();                temp.Add(item);                if (temp.Count == setLength)                {                    // 達到最大計算深度,表示完成一個全排列,添加                    permutations.Add(temp.ToArray());                }                else                {                    CalculatePermutationCrude(permutations, temp, collection, setLength);                }            }        }    }}

原理是有多少個元素,就循環多少次,將包含重復元素的排列剔除掉,自然就是集合的全排列了。

深度優先遍歷解法

代碼如下:

/// <summary>        /// 計算指定元素集的全排列        /// </summary>        /// <typeparam name="T">元素的具體類型</typeparam>        /// <param name="set">元素集</param>        /// <returns>全排列</returns>        public static IEnumerable<T[]> CalculatePermutationDFS<T>(IEnumerable<T> set)        {            var permutations = new List<T[]>();            var path = new List<T>();            bool[] visited = new bool[set.Count()];            CalculatePermutationDFS(set, permutations, path, visited);            return permutations;        }        /// <summary>        /// 計算指定元素集的全排列        /// </summary>        /// <typeparam name="T">元素的具體類型</typeparam>        /// <param name="set">元素集</param>        /// <param name="permutations">全排列</param>        /// <param name="path">排列的元素列表</param>        /// <param name="visited">元素訪問與否的數組</param>        private static void CalculatePermutationDFS<T>(            IEnumerable<T> set,            List<T[]> permutations,            List<T> path,            bool[] visited)        {            if (path.Count == set.Count())            {                permutations.Add(path.ToArray());            }            for (int i = 0; i < set.Count(); i++)            {                if (!visited[i])                {                    path.Add(set.ElementAt(i));                    visited[i] = true;                    CalculatePermutationDFS(set, permutations, path, visited);                    path.RemoveAt(path.Count - 1);                    visited[i] = false;                }            }        }

在代碼中使用了一個輔助列表保存遍歷過的元素,一個輔助數組保存元素的訪問情況,在深度遍歷前設置相關信息,遍歷完成后重置相關信息。

非遞歸解法

上面的兩種解法使用了遞歸,眾所周知,全排列的個數為待排列個數的階乘。而在數據量較大時,階乘比指數爆炸更可怕。如果不使用自建堆棧,將遞歸化為迭代,有沒有其他辦法計算全排列,就像前面計算笛卡爾積一樣,將每個數字映射到一個解。經過多次試錯,總算被我想到了一個辦法。

將每一個全排列對應一個數,以1234為例,如下圖:

1

將每個序號(從0開始)對應到一個數。對應數的有如下規律:

  1. 位數總是比全排列的元素個數少1。
  2. 設從右到左,每個數位對應的權值依次遞增,最右邊個數權植為1。則對應數的每位上的數值為序號除以位數權值的階乘然后對其位數的權值加1取余(真是太繞了)。注:在程序運算中轉型會直接向下取整。以23為例:第1位(23/1!)%2=23%2=1;第2位(23/2!)%3=11%3=2,第3位(23/3!)%4=3再以13為例,第1位(13/1!)%(2)=13%1=1;第2位(13/2!)%3=6%3=0,第三位(13/3!)%4=2。
  3. 從對應數到全排列,只需要從左到右,依次在元素集中取出剩余數中從小到大的第對應數數位位上的數(從0開始計數,同樣還是很繞),最后還將剩下的數取出即可。示例如下:

1

終于可以上代碼了:

/// <summary>        /// 計算指定元素集的全排列        /// </summary>        /// <typeparam name="T">元素的具體類型</typeparam>        /// <param name="collection">元素集</param>        /// <returns>全排列</returns>        public static IEnumerable<T[]> CalculatePermutation<T>(IList<T> collection)        {            // 全排列總數            int total = 1;            // 元素個數            int elementCount = collection.Count;            // 除數列表,用于計算每個全排列的情況            var dividers = new int[elementCount - 1];            for (int i = 2; i <= elementCount; i++)            {                dividers[i - 2] = total;                total *= i;            }            // 全排列列表            var permutations = new T[total][];            // 計算全排列,共有permutationNumber個全排列,            // 從0到permutationNumber中,每個數字對應一種全排列情況            for (int counter = 0; counter < total; counter++)            {                // 一個全排列的情況                var permutation = new T[elementCount];                // 指示數組,指示全排列對應元素集中的位置                var indicates = new int[elementCount - 1];                // 使用數組,指示元素集中對應的元素是否已使用                var usedFlags = new bool[elementCount];                for (int j = 0; j < elementCount - 1; j++)                {                    // 從右向左計算                    indicates[elementCount - 2 - j] = (counter / dividers[j]) % (j + 2);                }                // 全排列的索引                int index = 0;                foreach (var indicate in indicates)                {                    int pos = 0;                    // 統計未使用的元素                    int unusedCount = -1;                    for (; pos < elementCount; pos++)                    {                        if (!usedFlags[pos])                        {                            unusedCount++;                        }                        // 找到了要放入的元素位置                        if (unusedCount >= indicate)                        {                            break;                        }                    }                    permutation[index] = collection[pos];                    usedFlags[pos] = true;                    index++;                }                // 將最后剩余的元素放入全排列                for (int j = 0; j < elementCount; j++)                {                    if (!usedFlags[j])                    {                        permutation[elementCount - 1] = collection[j];                        break;                    }                }                permutations[counter] = permutation;            }            return permutations;        }

答案

經過一番勞累,結局是悲傷的,答案就是沒有答案。可能有的朋友會說特殊運算,由于題目的限制,冪跟對數是不可能了,唯一能夠使用的特殊運算就只有平方,在這種情況下,依然沒有答案。當然,如果你硬要說立方也是特殊運算,那么還是有解的。

此刻我的內心是崩潰的


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美大秀在线观看| 最新亚洲国产精品| 亚洲国产中文字幕在线观看| 亚洲人成在线观看网站高清| 国产欧美一区二区三区视频| 国产欧美在线视频| 成人福利网站在线观看11| 日韩在线观看你懂的| 日韩中文在线观看| 91麻豆国产精品| 欧美最猛性xxxxx(亚洲精品)| 久久精品国产欧美激情| 欧美刺激性大交免费视频| 国产91精品久| 97在线看免费观看视频在线观看| 欧美黑人极品猛少妇色xxxxx| 亚洲电影免费观看高清完整版在线| 国产午夜精品免费一区二区三区| 91高清视频免费观看| 6080yy精品一区二区三区| 2019中文字幕在线观看| 97超级碰在线看视频免费在线看| 92版电视剧仙鹤神针在线观看| 欧美猛少妇色xxxxx| 久久99国产综合精品女同| 国产美女精品免费电影| 欧美日本啪啪无遮挡网站| 97国产成人精品视频| 欧美黄色三级网站| 欧美黑人巨大xxx极品| 精品久久久久人成| 91久久精品国产91久久性色| 亚洲精品国产拍免费91在线| 亚洲一区二区三区视频播放| 国产精品小说在线| 主播福利视频一区| 美女精品视频一区| 最近日韩中文字幕中文| 欧美亚洲国产视频小说| 欧美日本啪啪无遮挡网站| 国产亚洲精品美女久久久| 91香蕉嫩草影院入口| 国产精品福利久久久| 色偷偷噜噜噜亚洲男人| 国产丝袜一区视频在线观看| 成人激情视频免费在线| 国产在线精品成人一区二区三区| 毛片精品免费在线观看| 国内精品400部情侣激情| 国产黑人绿帽在线第一区| 亚洲一区二区免费| 最近2019年好看中文字幕视频| 国产丝袜视频一区| 国产91对白在线播放| 欧美第一黄色网| xvideos亚洲人网站| 日韩欧美精品网址| 久久精品视频在线播放| 日韩中文字幕网站| 日韩美女毛茸茸| 亚洲国产精品va| 久久露脸国产精品| 欧美激情va永久在线播放| 亚洲精品女av网站| 亚洲成人久久久| 欧美日本黄视频| 欧美日韩国产成人在线观看| 欧美日本黄视频| 一区二区三欧美| 国产综合在线观看视频| 亚洲第一中文字幕| 国产精品日日摸夜夜添夜夜av| 国产精品第七十二页| 欧美亚洲激情视频| 亚洲激情第一页| 日本高清久久天堂| 久久久国产精品视频| 国产国产精品人在线视| 欧美色道久久88综合亚洲精品| 欧美大片免费看| 最好看的2019年中文视频| 91亚洲精品久久久久久久久久久久| 亚洲春色另类小说| 亚洲精品国产品国语在线| 欧美亚洲视频在线观看| 岛国视频午夜一区免费在线观看| 姬川优奈aav一区二区| 中文日韩在线观看| 国产精品扒开腿做爽爽爽男男| 成人福利网站在线观看| 日韩欧美亚洲国产一区| 国产精品久久久精品| 91久久久亚洲精品| 久久精品亚洲精品| 国产精品久久91| 日韩在线播放视频| 亚洲一区二区三区777| 欧美激情综合色| 欧美成年人视频网站欧美| 亚洲成人av中文字幕| 日韩av在线免费播放| 91沈先生在线观看| 国产精品激情自拍| 精品调教chinesegay| 日韩天堂在线视频| 欧美日韩国产中字| 91香蕉嫩草神马影院在线观看| 欧美成人午夜激情| 欧美黑人一级爽快片淫片高清| 日韩电影中文字幕| 美日韩精品视频免费看| 欧美一区三区三区高中清蜜桃| 国产在线观看91精品一区| 日韩**中文字幕毛片| 久久成人一区二区| 亚洲精品成人网| 欧美成人中文字幕在线| 日韩av中文字幕在线免费观看| 欧美一级片一区| 国模精品系列视频| 另类专区欧美制服同性| 日本久久久久久久久久久| 欧美在线视频一区| 亚洲精品白浆高清久久久久久| 日韩欧美在线视频观看| 欧美日韩第一页| 国内外成人免费激情在线视频网站| 久久久亚洲福利精品午夜| 国产精品成人免费电影| 欧美性xxxxxx| 亚洲影院高清在线| 91亚洲va在线va天堂va国| 国产亚洲精品久久久久动| 日本a级片电影一区二区| 久久露脸国产精品| 米奇精品一区二区三区在线观看| 国产va免费精品高清在线| 欧美激情亚洲自拍| 欧美午夜激情小视频| 国产精品国产三级国产专播精品人| 国产精品情侣自拍| 国产精品直播网红| 国产精品香蕉在线观看| 日本韩国欧美精品大片卡二| 亚洲一区av在线播放| 国产精品久久久久高潮| 国产精品成人va在线观看| 国产精品久久不能| 精品免费在线观看| 久久久精品久久久久| 欧美日韩在线免费| 亚洲天堂日韩电影| 亚洲一区二区在线播放| 欧美大片网站在线观看| 欧美成年人视频| 国外色69视频在线观看| 欧美wwwxxxx| 91手机视频在线观看| 国产精品一区二区三区在线播放| 日本一区二三区好的精华液| 日韩欧美国产激情| 国产精品日韩欧美大师| 欧美日韩免费看| 欧美丰满少妇xxxxx做受|