一时技痒 不用模拟第一印象的构造 通过三个观察得来的规律解决N^2个往返接力问题...
生活随笔
收集整理的這篇文章主要介紹了
一时技痒 不用模拟第一印象的构造 通过三个观察得来的规律解决N^2个往返接力问题...
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
問題原題? 見銀河使者的隨筆? http://www.cnblogs.com/nokiaguy/archive/2009/07/24/1530139.html
第一印象? 我得到了和他一樣的解法,就是用斜切片,每一層的 x-1和y+1? 來控制順序寫數字的筆落在哪一個坐標。
但是根據一段時間的觀察? 我發現了幾個規律 可以讓我們不用模擬整個順序的流
首先我們觀察每一個切片
我們發現 在 n,n 坐標上的每一個數字都是這個切片對稱 而且是平均值。 經過簡單的計算? 我們發現 1-n個切片的平均值 都是(n*n +1)/2
繼續觀察 又發現規律了。? 這個矩陣對角對稱的任意兩個格子?? 正好是距離整個數列中心距離相等的兩點? 比如1和100 20和81?? 他們的和必為 max*max +1
這樣我們只要能推算出某一行或者某一列的值?? 就可以通過上面兩個特征來生成整個矩陣了哦
但是這個矩陣的行列太亂了 很難找出規律?這個時候就要考慮更簡單的模型
我們看看非首尾接力的矩陣
1
1 2
3
1 2 4
3 5
6
1 2 4 7
3 5 8
6 9
10
有沒有發現? 粗體的數字 剛好是之前所有斜切片的總和?
那么 順序矩陣和接力矩陣 有什么異同呢?
我們可以把接力矩陣當成隔行反轉的順序矩陣。這樣我們就得到了一個在 x,y軸上擺動的參考值。? 有了參考值? 就可以根據前兩點進行矩陣生成了
Code
???static?void?Main(string[]?args)
????????{
????????????var?max?=?11;
????????????int?[,]?mx=new?int?[max,max];
????????????var?sideval?=?0;
????????????for?(var?seed?=?0;?seed?<?max;?seed++)
????????????{
???????????????
????????????????int?parevalue?=?(seed?+?1)?*?(seed?+?1)?+?1;//規律1?中心軸對稱兩數之和等于層數平方+1?
????????????????bool?isOdd?=?seed?%?2?==?1;
????????????????sideval?=?sideval?+?seed?+?1;???//規律2?兩邊至少有一個數字為?1+2+3+4++n
????????????????for?(var?fillseed?=?seed;?fillseed?>=0;?fillseed--)
????????????????{
????????????????????int?row,?col;
????????????????????if?(!isOdd)
????????????????????{
????????????????????????row?=?fillseed;
????????????????????????col?=?seed?-?fillseed;
????????????????????}
????????????????????else
????????????????????{
????????????????????????col?=?fillseed;
????????????????????????row?=?seed?-?fillseed;
????????????????????}
????????????????????//規律1?中心軸對稱兩數之和等于層數平方+1?
????????????????????mx[col,?row]?=?sideval?-?fillseed;
????????????????????mx[row,?col]?=?parevalue?-?mx[col,?row];??
????????????????????//規律3?中心對稱的和為?max*max+1
????????????????????mx[max?-?col?-?1,?max?-?row?-?1]?=?max?*?max?+1?-?mx[col,?row];
????????????????????mx[max?-?row?-?1,?max?-?col?-?1]?=?max?*?max?+?1?-?mx[row,?col];
????????????????}
????????????}
????????????for?(var?x?=?0;?x?<?max;?x++)
????????????{
????????????????for?(var?y?=?0;?y?<?max;?y++)
????????????????{
????????????????????Console.Write(string.Format?("?{0:d3}"?,mx[x,?y]));
????
????????????????}
????????????????Console.WriteLine();
????????????}
????????????????Console.Read();
????????}
解法有很多種? 這種無疑是很生澀的。 作為面試題目的話? 并不建議寫這種考官很難理解的解法,會有小鞋
作為頭腦風暴? 防止老年癡呆 這個還是有一定意義的
第一印象? 我得到了和他一樣的解法,就是用斜切片,每一層的 x-1和y+1? 來控制順序寫數字的筆落在哪一個坐標。
但是根據一段時間的觀察? 我發現了幾個規律 可以讓我們不用模擬整個順序的流
首先我們觀察每一個切片
| 1 | 3 | 4 | 10 | 11 | 21 | 22 | 36 | 37 | 55 |
| 2 | 5 | 9 | 12 | 20 | 23 | 35 | 38 | 54 | 56 |
| 6 | 8 | 13 | 19 | 24 | 34 | 39 | 53 | 57 | 72 |
| 7 | 14 | 18 | 25 | 33 | 40 | 52 | 58 | 71 | 73 |
| 15 | 17 | 26 | 32 | 41 | 51 | 59 | 70 | 74 | 85 |
| 16 | 27 | 31 | 42 | 50 | 60 | 69 | 75 | 84 | 86 |
| 28 | 30 | 43 | 49 | 61 | 68 | 76 | 83 | 87 | 94 |
| 29 | 44 | 48 | 62 | 67 | 77 | 82 | 88 | 93 | 95 |
| 45 | 47 | 63 | 66 | 78 | 81 | 89 | 92 | 96 | 99 |
| 46 | 64 | 65 | 79 | 80 | 90 | 91 | 97 | 98 | 100 |
繼續觀察 又發現規律了。? 這個矩陣對角對稱的任意兩個格子?? 正好是距離整個數列中心距離相等的兩點? 比如1和100 20和81?? 他們的和必為 max*max +1
這樣我們只要能推算出某一行或者某一列的值?? 就可以通過上面兩個特征來生成整個矩陣了哦
但是這個矩陣的行列太亂了 很難找出規律?這個時候就要考慮更簡單的模型
我們看看非首尾接力的矩陣
1
1 2
3
1 2 4
3 5
6
1 2 4 7
3 5 8
6 9
10
有沒有發現? 粗體的數字 剛好是之前所有斜切片的總和?
那么 順序矩陣和接力矩陣 有什么異同呢?
| 1 | 3 | 4 | 10 | 11 | 21 | 22 | 36 | 37 | 55 |
| 2 | 5 | 9 | 12 | 20 | 23 | 35 | 38 | 54 | 56 |
| 6 | 8 | 13 | 19 | 24 | 34 | 39 | 53 | 57 | 72 |
| 7 | 14 | 18 | 25 | 33 | 40 | 52 | 58 | 71 | 73 |
| 15 | 17 | 26 | 32 | 41 | 51 | 59 | 70 | 74 | 85 |
| 16 | 27 | 31 | 42 | 50 | 60 | 69 | 75 | 84 | 86 |
| 28 | 30 | 43 | 49 | 61 | 68 | 76 | 83 | 87 | 94 |
| 29 | 44 | 48 | 62 | 67 | 77 | 82 | 88 | 93 | 95 |
| 45 | 47 | 63 | 66 | 78 | 81 | 89 | 92 | 96 | 99 |
| 46 | 64 | 65 | 79 | 80 | 90 | 91 | 97 | 98 | 100 |
我們可以把接力矩陣當成隔行反轉的順序矩陣。這樣我們就得到了一個在 x,y軸上擺動的參考值。? 有了參考值? 就可以根據前兩點進行矩陣生成了
Code
???static?void?Main(string[]?args)
????????{
????????????var?max?=?11;
????????????int?[,]?mx=new?int?[max,max];
????????????var?sideval?=?0;
????????????for?(var?seed?=?0;?seed?<?max;?seed++)
????????????{
???????????????
????????????????int?parevalue?=?(seed?+?1)?*?(seed?+?1)?+?1;//規律1?中心軸對稱兩數之和等于層數平方+1?
????????????????bool?isOdd?=?seed?%?2?==?1;
????????????????sideval?=?sideval?+?seed?+?1;???//規律2?兩邊至少有一個數字為?1+2+3+4++n
????????????????for?(var?fillseed?=?seed;?fillseed?>=0;?fillseed--)
????????????????{
????????????????????int?row,?col;
????????????????????if?(!isOdd)
????????????????????{
????????????????????????row?=?fillseed;
????????????????????????col?=?seed?-?fillseed;
????????????????????}
????????????????????else
????????????????????{
????????????????????????col?=?fillseed;
????????????????????????row?=?seed?-?fillseed;
????????????????????}
????????????????????//規律1?中心軸對稱兩數之和等于層數平方+1?
????????????????????mx[col,?row]?=?sideval?-?fillseed;
????????????????????mx[row,?col]?=?parevalue?-?mx[col,?row];??
????????????????????//規律3?中心對稱的和為?max*max+1
????????????????????mx[max?-?col?-?1,?max?-?row?-?1]?=?max?*?max?+1?-?mx[col,?row];
????????????????????mx[max?-?row?-?1,?max?-?col?-?1]?=?max?*?max?+?1?-?mx[row,?col];
????????????????}
????????????}
????????????for?(var?x?=?0;?x?<?max;?x++)
????????????{
????????????????for?(var?y?=?0;?y?<?max;?y++)
????????????????{
????????????????????Console.Write(string.Format?("?{0:d3}"?,mx[x,?y]));
????
????????????????}
????????????????Console.WriteLine();
????????????}
????????????????Console.Read();
????????}
解法有很多種? 這種無疑是很生澀的。 作為面試題目的話? 并不建議寫這種考官很難理解的解法,會有小鞋
作為頭腦風暴? 防止老年癡呆 這個還是有一定意義的
轉載于:https://www.cnblogs.com/waynebaby/archive/2009/07/25/1530653.html
總結
以上是生活随笔為你收集整理的一时技痒 不用模拟第一印象的构造 通过三个观察得来的规律解决N^2个往返接力问题...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux中常用的查找文件的命令
- 下一篇: 11个顶级 JavaScript 日历插