趣味算法-三色旗
一条绳子挂红白蓝三种颜色的旗子,且排列无序,现用程序把三种旗子同色归类,顺序为红-白-蓝,每次只能交换2面旗子,采用最少步骤完成。
算法描述:只需把红色和蓝色的旗子进行交换,红旗和篮旗都就位后,白旗自然就位。
1) 从前向后设定红旗的最后位置,如果该位置不是红旗,向后扫描旗子队列,如果发现红旗则与当前红旗位置的旗子交换。
2) 如果该位置是红旗,则向后移动红旗的最后位置。
3) 从后向前设定篮球的最前位置,如果该位置不是蓝旗,向前扫描旗子队列,如果发现蓝旗则与当前红旗位置的旗子交换。
4) 如果该位置是蓝旗,则向前移动蓝旗的最后位置。
#include <stdio.h>
// the correct order should be Blue, White, Red
int MakeOrder(char arrFlagQueue[], int nLen)
{
int nSetRPos = 0, nSetBPos = 0;
int nForward = 0, nBackward = 0;
int i = 0, j = 0;
if ((nLen == 0) || (nLen == 1))
return 0;
nSetBPos = nLen - 1;
nBackward = nSetBPos - 1;
nForward = nSetRPos + 1;
for (i = 0; i < nLen; i++)
{
if (arrFlagQueue[nSetRPos] != 'R')
{
while (nForward <= nSetBPos)
{
if (arrFlagQueue[nForward] != 'R')
{
nForward++;
}
else
{
arrFlagQueue[nForward] = arrFlagQueue[nSetRPos];
arrFlagQueue[nSetRPos] = 'R';
nSetRPos++;
for (j = 0; j < nLen; j++)
{
printf("%c ", arrFlagQueue[j]);
}
printf("\n\n");
break;
}
}
}
else
{
nSetRPos++;
}
if (arrFlagQueue[nSetBPos] != 'B')
{
while(nBackward >= nSetRPos)
{
if (arrFlagQueue[nBackward] != 'B')
{
nBackward--;
}
else
{
arrFlagQueue[nBackward] = arrFlagQueue[nSetBPos];
arrFlagQueue[nSetBPos] = 'B';
nSetBPos--;
for (j = 0; j < nLen; j++)
{
printf("%c ", arrFlagQueue[j]);
}
printf("\n\n");
break;
}
}
}
else
{
nSetBPos--;
}
}
return 0;
}
int main()
{
int n = 0;
char arrTest1[10] = {'B','W','R','B','W','R','B','B','W','W',};
char arrTest2[2] = {'W','W'};
for(n = 0; n < 10; n++)
{
printf("%c ", arrTest1[n]);
}
printf("\n\n");
MakeOrder(arrTest1, 10);
printf("=======================\n\n");
for(n = 0; n < 2; n++)
{
printf("%c ", arrTest2[n]);
}
printf("\n\n");
MakeOrder(arrTest2, 2);
scanf("%d", &n);
return 0;
}
算法复杂度:
最差:队列中全为白旗
O(n) = N * N * N