[C#]有n個小孩排成一圈。從第1個小孩開始作1至3報數,凡報數3的小孩從圈中出來,求最後出圈的小孩的順序號是多少?

網上很多類似的文章,但大致都是用C語言做的,這裏就以C#語言做的!

稍做改變,我們以5個人,依次報數1234,報4的離開進行分析。

5個人對應5個編號,也就是編號1,2,3,4,5,最後留下來的人是留下來的編號,這個不要弄暈了。
然後給每一個人一個索引,索引從1開始,那麼5個人分別對應的索引也就s[1],s[2]...
那麼我們也就知道編號4對應的索引也就是4了,開始是從編號1開始報數的,編號1對應的索引也是1,
那麼我們就把每一輪報數爲1的索引定義爲num,也就是num=1


第一輪:編號4報的是數字4,而編號4對應的索引也就是4,報4的出去,那麼後面編號5也就
填充到s[4]的位置了,那麼接下來報1的人也就是編號5了,編號5對應的索引此時是4,也就
是num=4


第二輪:編號5開始報1,轉到報4時就是編號3了,編號3對應的索引還是3,此時編號3也就要
出去了,後面的又要往前面填了,編號3後面的也就是編號5了,還是編號5開始報數,此時編
號5對應的索引也就是3,也就是num=3,s[3]=編號5


第三輪:此時留下的人只剩編號1,2,5了,編號5開始報1,報到4的時候是編號5,那麼編
號5移除掉,那麼接下來報1的也就是編號1了,也就是num=1


第四輪:編號1開始報1,很明顯報到4的也就是編號2了,那麼結果留下來的就是編號1了。


通過上面規律,不難發現,在沒開始報數時,num=1,第一輪結束,num=4,人數=4人,
第二輪:num=3,人數3人,第三輪:num=1,人數2
  因此得到的公式是:num=(num+4-1)%當前人數
測試下看是不是:num=1時,當前人數5人,輸出num=4,也就是接下來報1的人是索引4
對應的編號,也就是編號5了,因爲編號4已經移除掉了,再進行第二輪時,此時num=4,當前人數4人,輸出的num=3,
也就是索引爲3的編號3退出了,此時現在就剩下編號1,2,5,那麼編號5現在對應的索引是幾多勒?
(答案是:3),那麼接下來報1的是編號幾勒?(答案是編號5,也就是索引3),此時num=3
第三輪:num=3,人數爲3人,輸出的num=6%3=0,發現沒有餘數?怎麼辦?問題又來了:


例:編號1,2,3,4依次報數1234,報4的出去
num= (1+4-1)/4=0,出去的人是編號4,而接下來報1的也就是編號1了,也就是num要等於1,
於是我又發現規律了,當沒有餘數時,也就是num=0時,我把num=當前人數,再測試下看看,
編號4出去前,當前人數爲4,把num=4賦值,進入下一次,此時人數是3人,num=(4+4-1)%3=1,也就是
接下來報1的編號是索引1對應的編號了,也就是編號1....



認真思考的話,看到這裏,你可能明白了點吧,注意的是,每移除一個編號時,後面的人的編號對應的索引都-1了,
就好比最先開始s[4]=編號4,s[5]=編號5,編號4移除去後,此時s[4]也就是編號5了...



再提最後一點,每輪的索引num對應的編號是開始數1的人!


暈了的話就慢慢體會吧,要是這還看不懂?再看3遍,還看不懂,你拿刀砍我吧!


分析就到這裏,下面是代碼,可對照代碼再分析分析!!!


   int j, k = 1, total = 5, start = 1, alter = 4;
            int[] count = new int[total + 1];
            int[] s = new int[total + 1];
            for (int i = 1; i <= total; i++)
            {
                s[i] = i;
            }
            
            for (int i = total; i >= 2; i--)
            {
                start = (start + alter - 1) % i;
                if (start == 0)
                {
                    start = i;
                }
                count[k] = s[start];
                k++;
                for (j = start + 1; j < i; j++)
                {
                    s[j - 1] = s[j];
                }

            }
            count[k] = s[1];
            Console.WriteLine("最後一個留在圈裏的小孩編號是:{0}", count[k]);




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章