• 【三色旗】


    /*
    三色旗
    说明:
    三色旗的问题最早由E.W.Dijkstra所提出,他所使用的用语为Dutch Nation Flag(Dijkstra为荷兰人),而大多数
    的作者则使用Three-Color Flag来称之。
    
    假设有一条绳子,上面有红,白,蓝三种颜色的旗子,起初绳子上的旗子颜色并没有顺序,您希望将之分类,并
    排列为蓝,白,红的顺序,要如何移动次数才会最少,注意您只能在绳子上进行这份动作,而且一次只能调换
    两个色旗子。
     
    解法:
    在一条绳子上移动,在程式中也就意味着只能使用一个阵列,而不能使用其他的阵列来作辅助,问题的解法很简单
    您可以自己想像一下在移动旗子,从绳子开头进行,遇到蓝色往前移,遇到白色留在中间,遇到红色往后移,如下
    所示:
    只是要让移动的次数最少的话, 就要有些技巧:
        1.如果图中W所在位置为白色,则W+1, 表示未处理的部分移至白色群组。
        2.如果W部分为蓝色, 则B与W的元素对调,而B与W必须各 +1, 表示两个群组都多了一个元素。
        2.如果W所在的位置是红色,则将W与R交换,但R要减 1,表示未处理的部分减 1.
        
    注意B,W,R并不是三色旗的个数,它们只是一个移动的指标;什么时候移动结束呢?一开始时未处理的R指标会是
    等于旗子的总数,当R的索引数减至少于W的索引数时,表示接下来的旗子就是红色了,此时就可以结束移动,如下
    所示: 
    */
    
    #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', ''};
        int wFlag = 0; 
        int bFlag = 0;
        int rFlag = strlen(color) - 1;
        int i, count = 0;
        
        for(i = 0; i < strlen(color); i++)
        {
            printf("%c", color[i]);
        }
        printf("
    ");
        
        printf("开始: 
    ");
        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("
    ");
            count++;
        }
        
        printf("
    最终:
    ");
        for(i = 0; i < strlen(color); i++)
        {
            printf("%c", color[i]);
        }
        printf("
    共移动了 %d 次.", count);
        printf("
    ");
        
        return 0;
    }

    运行结果:

    转载本博请联系作者! 如有问题请在评论区评论或者发邮件:@libras

  • 相关阅读:
    win7下的vxworks总结
    ubuntu 无法获得锁 /var/lib/dpkg/lock
    项目中用到了的一些批处理文件
    win7下安装 WINDRIVER.TORNADO.V2.2.FOR.ARM
    使用opencv统计视频库的总时长
    January 05th, 2018 Week 01st Friday
    January 04th, 2018 Week 01st Thursday
    January 03rd, 2018 Week 01st Wednesday
    January 02nd, 2018 Week 01st Tuesday
    January 01st, 2018 Week 01st Monday
  • 原文地址:https://www.cnblogs.com/libra-yong/p/6296244.html
Copyright © 2020-2023  润新知