アルゴリズム毎週質問003:プ

問題:

そこ100は100にデジタルカード1を読み込み、順次配置されています。最初に、全てのカードが裏側のアップです。最初の2枚のカードから誰かが、一人一プ。次いで、2、4、6、...、100枚のカードはサイドアップとなるであろう。次に、最初の3枚のカードから別の人、プ毎に2つ(バックアップ元は、上向きフリップ;オリジナルフェイスアップは、バックアップにフリップ)。その後、再び、最初の4枚のカードからの人、すべての3枚のフロップカードがあります。したがって、n番目のカードから開始し、すべてのN-1カードフロップは、無カードまで反転します。
アルゴリズム毎週質問003:プ
すべてのカードはなくなった変更を求めている場合は、すべてのバックアップカード番号の。

アイデア:

多くのアイデアこの質問があります。

アイデア1つの
1、99から最後まで始め、円形である私。Jインデックスカード。
カードの一つ一つの主題に応じてすべてのラウンドは、対応するフリップフロッの質問の意味を見つけるために。

2考える
1、99から最後まで始め、円形である私を、そしてjはインデックスカードです。
フリップの要件を満たすために、すべてのカード上のすべてのラウンド。

3枚のアイデアの
偶数がバックアップ反転するカードのみ。
カードは、タイミングの上になっている:とき図示し、理解することは非常に簡単ではありません、ブランド、のための顔についてのステップ数。
例えば:4プレート、バックアップ最初に、
1ラウンド、開始から2プレートは、ステップ2,4プレートを右側跳ね上げされ、
ラウンド2、プレート3から出発して、ステップサイズ; 3,4-プレートが回転されていない
、プレート4から出発して、3から4,4プレートをバックアップ反転するステップ;
彼は反転されないであろう

なお、ステップ長が2,4である場合、4旋回プレートが発生する、ことを見ることができ、除数は2と4×4です。

例えば:プレート6、最初のバックアップで、
1ラウンド、プレート2から始めて、2,6プレートのステップで右側跳ね上げされ、
ラウンド2、プレート3から出発して、ステップサイズ3,6-プレートをバックアップ反転され、
3の、プレートから出発4、4,6-プレートのステップサイズは回転されず、
4から5はプレートから開始し、5,6-ステッププレートが回転されず、
5、6をプレートから出発して、6,6プレートのステップサイズは右側を跳ね上げている。
彼は反転されません

あなたは、ステップサイズが2,3,6のとき番号2,3,6は約6をしている一方で、6プレートのフリップは、発生していることがわかります。
この数は、すべての自然数についてのカウントである場合には、鳥の提供数の数が奇数で、最終的にバックに直面します。

あなたは要約し続けることができます。

例えば:
12ナンバープレート、数は約1,2,3,4,6,12、6つの除数の合計が、最終的に表向き;
16ナンバープレート、数約1,2,4,8,16、 ; 5つの公約数は、最終的に後部に面している、ある
; 25枚のプレート、約1,5,25番号、約3の総数から、最終的にバックアップされ
、バックアップカード4,16のすべてが、注目します平方数ある25、。
だから、この質問は、最終的には、正方形を見つけるために、すべての1-100番号になります。

回答:

次の三つのアイデアは、上記のPHPコードとGolangを与えられています

PHP

// 按顺序进行翻牌,i为牌下标,j为牌下标+步长
function flip1()
{
    $size = 100;
    $cards = array_fill(0, $size, 0); // 初始化数组

    // i为轮次
    for ($i = 1; $i <= $size; $i++) {
        // 如果当前的牌是正面,就翻过来;反之亦然。
        // 每轮步长增长为i+1,
        // 例如:
        // 第一轮起始下标是1,步长是2(=1+1),翻1,3,5...下标的牌
        // 第二轮起始下标是2,步长是3(=2+1),翻2,5,8...下标的牌
        // 以此类推
        for ($j = $i; $j < $size; $j += $i + 1) {
            $cards[$j] = !$cards[$j];
        }
    }
    output($cards);
}

// i为轮次,j为牌下标
// 第1轮:2,4,6...100的牌被翻转,对应的下标为1,2,3...99,(j+1)%(1+1)==0
// 第2轮:3, 6, 9...99的牌被翻转,对应的下标为2,5,8...98,(j+1)%(2+1)==0
// 以此类推,得到公式,(j+1)%(i+1)==0时,牌都会翻转
function flip2()
{
    $size = 100;
    $cards = array_fill(0, $size, 0); // 初始化数组
    for ($i = 1; $i < $size; $i++) {
        for ($j = 1; $j < $size; $j++) {
            if (($j + 1) % ($i + 1) == 0) {
                $cards[$j] = !$cards[$j];
            }
        }
    }
    output($cards);
}

// 当牌i翻转为偶数次时,即为背面朝上
// 当j为i的约数时,会触发一次i的翻转
// 比如:牌4,会在约数为1,2,4时被翻转
// 但所有的牌都是从约数为2开始翻,所以排除掉约数1的情况
// 此时,4号牌只翻转了2次,符合偶数次翻转的情况,所以其最终是背面朝上
function flip3()
{
    $size = 100;
    $tmp = array();

    // i为牌面,数字为1-100的100张牌
    for ($i = 1; $i <= $size; $i++) {
        $flag = false;

        // j为步长
        for ($j = 2; $j <= $size; $j++) {
            if ($i % $j == 0) {
                $flag = !$flag;
            }
        }

        if ($flag == false) {
            $tmp[] = $i;
        }
    }
    echo implode(' ', $tmp) . "\n";
}

function output($cards)
{
    foreach ($cards as $key => $val) {
        if (!$val) {
            echo $key + 1;
            echo " ";
        }
    }
    echo "\n";
}

flip1();
flip2();
flip3();

輸出

1 4 9 16 25 36 49 64 81 100 
1 4 9 16 25 36 49 64 81 100 
1 4 9 16 25 36 49 64 81 100

Golang

package main

import "fmt"

var size = 100 // 牌数

func main() {
    Flip1()
    Flip2()
    Flip3()
}

// 初始化数据
func initCards() []bool {
    var cards []bool // 存放每张牌的状态
    for i := 0; i < size; i++ {
        cards = append(cards, false)
    }
    return cards
}

// 翻牌算法1
func Flip1() {
    cards := initCards()
    for i := 1; i < size; i++ {
        for j := i; j < size; j += i + 1 {
            cards[j] = !cards[j]
        }
    }
    PrintCards(cards)
}

// 翻牌算法2
func Flip2() {
    cards := initCards()
    for i := 1; i < size; i++ {
        for j := i; j < size; j++ {
            if (j+1)%(i+1) == 0 {
                cards[j] = !cards[j]
            }
        }
    }
    PrintCards(cards)
}

// 翻牌算法3
func Flip3() {
    var cards []int
    for i := 1; i <= size; i++ {
        flag := false
        for j := 2; j <= size; j++ {
            if i%j == 0 {
                flag = !flag
            }
        }
        if flag == false {
            cards = append(cards, i)
        }
    }
    fmt.Println(cards)
}

// 输出牌面
func PrintCards(cards []bool) {
    var results []int
    for i := 0; i < size; i++ {
        if cards[i] == false {
            results = append(results, i+1)
        }
    }
    fmt.Println(results)
}

輸出

[1 4 9 16 25 36 49 64 81 100]
[1 4 9 16 25 36 49 64 81 100]
[1 4 9 16 25 36 49 64 81 100]

おすすめ

転載: blog.51cto.com/ustb80/2421507