Poj1721カード

第Iカードの位置が[I]にカードのi番目の位置の交換後、[I]です。
交換など交換後の全ての配列位置、


既知の配列のm回交換した後、元のシーケンスを見つけます。

考える:

与えられた[i]は4756123です


変換したら、    

1 2 3 4 5 6 7 7 4 5 6 1 2 3 1 2 3 4 5 6 7
                     * =
4 7 5 6 1 2 3 6 3 1 2 4 7 5 6 3 1 2 4 5 7

二次変換
1,234,567,631,247,512,345。6. 7
                         * =
6 3 1,247,571,632,547,163,254

形質転換は3回行った
。1 2 3,456,771,632,541,234,567

                       * =
7 1 6 3 2 5 4 4 5 6 7 1 2 3 4 5 6 7 1 2 3

 

変換は、4756123を得るために3回行った後に


元の配列は、形質転換の際に第3のサイクルを発生します

一般的なケースを考えてみましょう。
元のシーケンス1〜N個の異なる数字なので、シーケンスは、少なくとも一つの置換基を含むことができ
、多くの形質転換後に肯定した後、

そこを循環する、される
と、今、私たちは、交換サイクルのセクションを見つけ、新しいシーケンスが知られており、交換、数
その後、RES - S%RES

二次スワップは、元の配列を取得します。
//は、循環節をresは、Sは、変換、分析の数であります

する#include <stdio.hに> 
する#include <string.hの> 
 
INT配列[1010]、ArrayA [1010]、ArrayB [1010]。
 
ボイドGetNextの(INT N)
{ 
    ため(INT iが= 1; I <= N; I ++)
        ArrayB [I] = ArrayA [ArrayA [I]]。
    以下のために(INT I 1 =; I <= N; I ++)
        ArrayA [I] = ArrayB [I]。
} 
 
BOOL IsSame(INT N)
{ 
    ための(iは1 = INT; iが<= N; iが++)
        (ArrayB [I] =配列[I]!)もし
            戻り偽。
    trueを返します。
} 
int型のmain()
{ 
    int型N、S。
    (〜scanf関数は( "%D%D"、&N、&S))しながら
    { 
        ため(; <I = N;整数iが1 = I ++)
        { 
            scanf関数( "%のD"、および配列[I])。 
            ArrayA [I] =配列[i]は、
        } 
        int型RES。
        用(RES = 1 ;; RES ++)
        { 
            GetNextの(N)。
            (IsSame(N))であれば
                ブレーク。
        } 
        INT M = RES - S%のRES。
        int型NUM = 0; 
        一方、(NUM <M)
        { 
            GetNextの(N)。
            NUM ++; 
        } 
        ため(INT I 1 =; I <= N; I ++)
            のprintf( "%D \ n"は、ArrayB [I])。
    } 
    0を返します。
} 

----------------  
免責事項:この記事はCSDNブロガー徒歩Shaonianラングのオリジナルの記事で、CC 4.0 BY-SAの著作権契約書に従ってください、複製、オリジナルのソースを添付してくださいリンクとこの文。
原文链接:HTTPS://blog.csdn.net/lianai911/article/details/39323335

  

おすすめ

転載: www.cnblogs.com/cutemush/p/12133472.html