輕松周賽賽題:能否被8整除


  練習題鏈接:http://student.csdn.net/mcs/programming_challenges

  給定一個非負整數,問能否重排它的全部數字,使得重排后的數能被8整除。 輸入格式: 多組數據,每組數據是一個非負整數。非負整數的位數不超過10000位。 輸出格式 每組數據輸出一行,YES或者NO,表示能否重排它的全部數字得到能被8整除的數。注意: 重排可以讓0開頭

 

  今天一個小學弟問我這道題怎么做,我直接回答他將數字全排列,驗證是否可被8整除,例如123的全排列:123、231、312、213、132、321   (共3!=6種)

  他聽我講后,問怎么做全排列,然后我上網找個了方法復制粘貼給他(這個,呵呵,這種方法網上肯定可以找到),他就屁顛屁顛的不理我了。全排列方法是驗證一個開發者能力最簡單有效的方法。

 


 

  以下為提供全排列處理此問題的方法,當然這種方法網上隨處可見:

 1 class Program
 2     {
 3         static int Count = 1;
 4         static int DivNum = 8;
 5 
 6         /*
 7          * 
 8          *  1,2:  {1,2},{2,1}
 9          *  1,2,3:   
10          *       {3,1,2},{1,3,2},{1,2,3}     ( {1,2}中隨機插入3 )
11          *       {3,2,1},{2,3,1},{2,1,3}     ( {2,1}中隨機插入3 )
12          * 
13          * 1,2,3,4:
14          *      就是在上面的六組數字中隨機插入4
15          * 
16          * 依次類推
17          */
18 
19         static void Main(string[] args)
20         {
21             string[] arr = new string[]
22             {
23              "11223344",
24              "23456798",
25              "89289238",
26              "23458203945829345"
27             };
28 
29             foreach (string item in arr)
30             {
31                 if (Perm(item.ToCharArray(), 0))
32                     Console.WriteLine("  {0}   Yes", item);
33                 else
34                     Console.WriteLine("  {0}   No", item);
35             }
36         }
37 
38         static void Swap(ref Char lc,ref Char rc)
39         {
40             Char tmp = lc;
41             lc = rc;
42             rc = tmp;
43         }
44 
45         static bool Perm(char[] arrChar, int cur)
46         {
47             if (cur == arrChar.Length - 1)
48             {
49                 long val1 = 0;
50 
51                 if (long.TryParse(new string(arrChar), out val1) && val1 % DivNum == 0)
52                 {
53                     return true;
54                 }
55                 else
56                     return false;
57             }
58             else
59             {
60                 for (int i = cur; i < arrChar.Length; i++)
61                 {
62                     Swap(ref arrChar[cur], ref arrChar[i]);
63                     if (Perm(arrChar, cur + 1))
64                         return true;
65                     Swap(ref arrChar[cur], ref  arrChar[i]);
66                 }
67             }
68             return false;
69         }
70     }
C# 完全排列

全排列算法結果:

 

  還有一種更簡潔的方法,erlang語言,我記得在變位詞那個章節里,舉例就是全排列。大致如下:

-module(lib_misc).  
-export([perms/1]).  
perms([])   ->  [[]];  
perms(L)    ->  [ [H|T] || H <- L , T <- perms( L--[H] ) ].  
二郎 全排列

全排列算法結果:

 


 

 全排列方法在我之后審題中被拋棄了,因為這道題不能夠用全排列,里面有個條件很苛刻。

 

下面我把自己的思路提煉出來,以饗讀者。

 

   其實,這道題使用歸納法比較好,為什么?題目有提示 非負整數的位數不超過10000位 ,這意味着什么呢?非負整數的長度可能達到9999位,如果這么大的數使用全排列,估計計算機要死了,更何況我家自用開發機是8年前的老古董,想的出這種餿主意,它肯定受不了了。所以要借助歸納法,為什么可以用歸納法?呵呵,我猜的,別笑,我說得是實話,我猜測它可以使用歸納法,那么就得找出它遵循什么規律了,下面開始做一些假設過程:

 

 

 

  怎么樣,簡單吧,只要判斷末三位組成的數字能被8整除,這個數必然能被8整除,這是一道公務員考試題,別問我為什么知道哦,這是秘密。o(∩_∩)o 哈哈

 

  碰到問題,想都不想的去做,結果只有一種,徒勞無功,倒不如什么都不做。這道題我開始也是全排列,因為胸有成竹嘛,但是后來仔細看題后,發現問題不是那么回事,有一個可能很難達到的要求,就是位數達到9999位怎么計算?所以,最后我認真的分析了一下發現它似曾相識。呵呵。

 1             string aaa = "123123213840213849102384192034801923480192381234";
 2             int length = aaa.Length - 3;
 3 
 4             for (int x = 0; x < length; x++)//對應百位
 5             {
 6                 for (int y = 0; y < length; y++)//對應十位
 7                 {
 8                     if (y == x) 
 9                         continue;
10 
11                     for (int z = 0; z < length; z++)//對應個位
12                     {
13                         if (z == x || z == y)
14                             continue;
15 
16                         if (Convert.ToInt32(new string(new char[] { aaa[x], aaa[y], aaa[z] })) % 8 == 0)
17                         {
18                             char[] arr = aaa.ToCharArray();
19 
20                             Swap(ref arr[x], ref arr[length + 0]);
21                             Swap(ref arr[y], ref arr[length + 1]);
22                             Swap(ref arr[z], ref arr[length + 2]);
23 
24                             Console.WriteLine("重排后字符串 : " + new string(arr));
25                             goto GT_1;
26                         }
27                     }
28                 }
29             }
30 
31         GT_1: ;
簡單寫點

   好吧,就這么多吧。這個網站的試題還不錯,我看了不少,沒事可以去練習一下。http://student.csdn.net/mcs/programming_challenges


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM