• 三色旗帜分类


    问题描述:

    假设有一条绳子,上面有红、白、蓝三种颜色的旗子,起初绳子上的旗子颜色并没有顺序,您
    希望将之分类,并排列为蓝、白、红的顺序,要如何移动次数才会最少,注意您只能在绳子上
    进行这个动作,而且一次只能调换两个旗子。

    #include <iostream>
    #include <time.h>
    using namespace std;
    //三色旗算法:
    //假设有一条绳子,上面有红、白、蓝三种颜色的旗子,起初绳子上的旗子颜色并没有顺序,您
    //希望将之分类,并排列为蓝、白、红的顺序,要如何移动次数才会最少,注意您只能在绳子上
    //进行这个动作,而且一次只能调换两个旗子。
    
    //算法说明:要使用最少的个数,就是用一个脚标从头开始移动,碰到红色就放到前面,碰到蓝色就放到后面,白色的就不动
    //得要三个脚标,一个用来保存红色最后项的位置,一个保存蓝色的
    #define maxsize 30
    //0表示红色R,1表示白色W,2表示蓝色B
    #define RED 0
    #define WHITE 1
    #define BLUE 2
    
    int R = 0;//j记录红色旗帜的位置,初始话0
    int scan = 0;//游标,用于全局扫描
    int B = maxsize-1;//蓝色旗帜位置,初始化为最大位置的后一位
    
    //输出数组的信息,便于观察
    void printf_flag(int *line,int size)
    {
        for (int i = 0;i <= size-1;i++)
        {
            cout<<line[i]<<" ";
        }
        cout<<endl;
    }
    
    int correct_flag(int *line,int begin,int end)
    {
        int step = 0;//需要步数
        //游标赋值
        R = begin;
        B = end;
        //游标优化
        while(line[B] == BLUE)
        {
            B--;
        }
        while(line[R] == RED)
        {
            R++;
        }
        scan = R;
        //开始扫描
        while(scan <= B)//扫描终止条件,游标与末尾的蓝色游标相遇
        {
            while(line[B] == BLUE && B >= scan)
            {
                B--;
            }
            while(line[R] == RED && R <= scan)
            {
                R++;
            }
            int temp = line[scan];
            switch(line[scan])
            {
            case RED://红色,放入红色区
                line[scan] = line[R];
                line[R] = temp;
                step++;
                R++;
                if (line[scan] == BLUE)
                {
                    break;
                }
                scan++;
                break;
            case WHITE://假如是白色
                scan++;
                break;
            case BLUE://假如是蓝色
                line[scan] = line[B];
                line[B] = temp;
                step++;
                B--;
                if (line[scan] == RED)
                {
                    break;
                }
                scan++;
                break;
            default:
                break;
            }
            printf_flag(line,maxsize);
        }
        return step;
    }
    
    int main()
    {
        //定义一个数组,描述绳子上的旗帜
        int line[maxsize];
        srand((int)time(0));
        for (int i = 0;i < maxsize;i++)
        {
            line[i] = rand()%3;
        }
        printf_flag(line,maxsize); 
        int a = correct_flag(line,0,maxsize-1);
        cout<<"Total Steps:"<<a<<endl;
        system("pause");
        return 0;
     }
    程序代码

    程序执行结果

    代码看起来很长,但是有一部分主要用于代码优化,减少移动次数,比如每次循环开始时进行游标优化等,具体的实现在代码里面都有注释,就不多讲了,(PS,这个程序的容错性还比较差啊)

  • 相关阅读:
    sed命令详解 皇星客栈
    FD_set FD_zero 皇星客栈
    linux tr命令详解 皇星客栈
    解决中文乱码问题(Ubuntu) 皇星客栈
    FIFO深度 皇星客栈
    输入阻抗 皇星客栈
    APROM Data Flash LDROM 皇星客栈
    kubernetes 1.21 部署业务
    kubernetes 1.21部署 cephcsi rbd
    kubernetes 1.21 部署 dashboard
  • 原文地址:https://www.cnblogs.com/color-my-life/p/3260454.html
Copyright © 2020-2023  润新知