C语言三色旗问题
有一根绳子,上面有红、白、蓝三种颜色的旗子。绳子上旗子的颜色并没有顺序,现在要对旗子进行分类,按照蓝色、白色、红色的顺序排列。只能在绳子上进行移动,并且一次只能调换两面旗子,怎样移动才能使旗子移动的次数最少?
算法思想
旗子在绳子上移动,而且一次只能调换两面旗子,因此只要保证在移动旗子时,从绳子的开头开始,遇到蓝色旗子向前移动,遇到白色旗子则留在中间,而遇到红色的旗子则向后移动。要使移动次数最少,可以使用三个指针 b、w、r 分别作为蓝旗、白旗和红旗的指针。
若 w 指针指向的当前旗子为白色,则 w 指针增加 1,表示白旗部分增加一面。若 w 指针指向的当前旗子为蓝色,则将 b 指针与 w 指针所指向的旗子交换,同时 b 指针与 w 指针都增加 1,表示蓝旗和白旗部分都多了一个元素。若 w 指针指向的当前旗子为红色,则将 w 指针与 r 指针所指向的旗子交换,同时 r 指针减 1,即 r 指针向前移动,未处理的部分减 1。刚开始时,r 指向绳子中最后一个旗子,之后 r 指针不断前移,当其位于 w 指针之前,即 r 的值小于 w 的值时,全部旗子处理完毕,可以结束比较和移动旗子操作。
在程序中通过宏定义用大写字母 'B' 'W' 'R' 分别代表蓝色、白色和红色;字符数组 “char color[]”表示绳子上的各种颜色的旗子;旗子移动时通过一个 while 循环判断移动过程是否结束,在 while 循环中根据旗子的不同颜色进行不同的处理。
程序代码
#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 w=0;
int b=0;
int r=strlen(color)-1;
int i;
for(i=0;i<strlen(color);i++)
printf("%c ",color[i]);
printf("\n");
while(w<=r)
{
if(color[w]==WHITE)
w++;
else
{
if(color[w]==BLUE)
{
swap(b,w);
b++;
w++;
}
else
{
while(w<r&&color[r]==RED)
r--;
swap(r,w);
r--;
}
}
}
for(i=0;i<strlen(color);i++)
printf("%c ",color[i]);
printf("\n");
return 0;
}
调试运行结果
交换前旗子颜色排列顺序及按顺序最少次数移动旗子后的排列顺序如下所示:
R W B W W B R B W R
B B B W W W W R R R
总结
在该实例中,分别用语句“int w=0;”“int b = 0;”“int r=strlen(color)-1;”定义并初始化白旗、蓝旗、红旗的指针 w、b、r。在交换不同颜色旗子时,通过旗子的指针实现交换函数 swap 的功能。
- C语言三色旗问题
- 有一根绳子,上面有红、白、蓝三种颜色的旗子。
- 03-10 关注:0
- C语言整数逆序输出
- 将一个从键盘输入的整数存放到一个数组中,通过程序的运行按照数组中的逆序输出该整数,利用递归的方法解决问题。
- 03-10 关注:0
- C语言约瑟夫环问题
- 编号为 1,2,3,…,n 的 n 个人围坐一圈,任选一个正整数 m 作为报数上限值,从第一个人开始按顺时针方向报数,报数到 m 时停止,报
- 03-10 关注:0
- C语言输出等腰三角形
- 本实例要求从键盘输入任意整数 n,通过程序运行输出对应高度为 n 的等腰三角形。
- 03-10 关注:0
- C语言字符串加密和解密算法
- 在本实例中要求设计一个加密和解密算法。在对一个指定的字符串加密之后,利用解密函数能够对密文解密,显示明文信息。
- 03-09 关注:3
- C语言统计单词个数,单词个数算法
- 在实际生活中经常会遇到一个问题:写英语作文时,常常要求满足一定的字数。在以往,要么我们一个一个地数;要么我们估算一行的单词数,
- 03-09 关注:3
- C语言获取矩阵的最大值及其下标
- 本实例要求使用二维数组将一个 3×4 的矩阵中所有元素的最大值及其下标获取,通过该程序,掌握二维数组的引用知识。
- 03-09 关注:4