Algorithm-Gossip(4) 三色棋(Three

    xiaoxiao2021-04-14  34

    前言

    This Series aritcles are all based on the book 《经典算法大全》; 对于该书的所有案例进行一个探究和拓展,并且用python和C++进行实现; 目的是熟悉常用算法过程中的技巧和逻辑拓展。

    提出问题

    Algorithm Gossip: 三色棋(Three_Color_Flag)

    假设数组里面有若干个3种数 (1,2,3)要大的数靠后,小的数靠前,每次只能调换两个数,问怎么移动让次数最少。

    原题目:绳子上有三种三色的旗, “蓝白红”按照这个顺序分离,每次换两个旗。方案让最小换的次数。

    分析和解释

    在一条绳子上移动,在程式中也就意味只能使用一个阵列,而不使用其它的阵列来作辅助,问 题的解法很简单,您可以自己想像一下在移动旗子,从绳子开头进行,遇到蓝色往前移,遇到 白色留在中间,遇到红色往后移,如下所示: 只是要让移动次数最少的话,就要有些技巧: - 如果图中W所在的位置为白色,则W+1,表示未处理的部份移至至白色群组。 - 如果W部份为蓝色,则B与W的元素对调,而B与W必须各+1,表示两个群组都多了一个元素 。 - 如果W所在的位置是红色,则将W与R交换,但R要减1,表示未处理的部份减1。 注意B、W、R并不是三色旗的个数,它们只是一个移动的指标;什幺时候移动结束呢?一开始 时未处理的R指标会是等于旗子的总数,当R的索引数减至少于W的索引数时,表示接下来的旗 子就都是红色了,此时就可以结束移动

    代码

    c/c++ 实现

    #include <stdio.h> #include <stdlib.h> #include <string.h> #define BLUE 'b' #define WHITE 'w' #define RED 'r' #define SWAP(x,y) { char temp; \ temp = color[x]; \ color[x] = color[y]; \ color[y] = temp; } int main() { char color[] = {'r', 'w', 'b', 'w', 'w','b', 'r', 'b', 'w', 'r', '\0'}; int wFlag = 0; int bFlag = 0; int rFlag = strlen(color) - 1; int i; for(i = 0; i < strlen(color); i++) printf("%c ", color[i]); printf("\n"); while(wFlag <= rFlag) { if(color[wFlag] == WHITE) wFlag++; else if(color[wFlag] == BLUE) { SWAP(bFlag,wFlag); bFlag++; wFlag++; }else { while(wFlag < rFlag && color[rFlag] == RED) rFlag--; SWAP(rFlag,wFlag); rFlag--; } } for(i = 0; i < strlen(color); i++) printf("%c ", color[i]); printf("\n"); return 0; }

    python 实现

    def printc(color): for i in range(len(color)): print(color[i],end = "") print() color = ['r', 'w', 'b', 'w', 'w','b', 'r', 'b', 'w', 'r'] wFlag = 0; bFlag = 0; rFlag = len(color) - 1 printc(color) while(wFlag <= rFlag): if(color[wFlag] == 'w'): wFlag+=1; elif(color[wFlag] == 'b'): color[bFlag],color[wFlag] = color[wFlag],color[bFlag] bFlag+=1; wFlag+=1; else: while(wFlag < rFlag and color[rFlag] == 'r'): rFlag-=1 color[rFlag],color[wFlag] = color[wFlag],color[rFlag] rFlag-=1; printc(color)

    拓展和关联

    有兴趣的可以尝试下,是不是最优解,用动态规划验证下。

    后记

    可以向dp状态转变。/后面再深究。

    参考书籍

    《经典算法大全》维基百科
    转载请注明原文地址: https://ju.6miu.com/read-669816.html

    最新回复(0)