經典的三色旗問題


首先來看,什么是三色旗問題。

有一根繩子,上面有紅、白、藍三種顏色的旗子。繩子上旗子的顏色並沒有順序,現在要對旗子進行分類,按照藍色、白色、紅色的順序排列。只能在繩子上進行移動,並且一次只能調換兩面旗子,怎樣移動才能使旗子移動的次數最少?

此為簡述的三色旗問題。

這次,我們就來研究一下三色旗問題。

我們將它簡單化。顏色什么的忽略。

我們將它理解為一個數組,有1,2,3;組成。且為無序的。

我們的任務就是將它按照前面均為1,緊接着為2,3,的數列。

當然解法有很多種。

比如說:多來幾個數組,將它拆開。

再比如,我們記錄各成分的個數。再分別輸出。

在這里呢,我們討論一種盡量簡單,移動次數最少的算法。

那么,現在我們開始分析該算法。

我們定義三個變量,兩個為0,一個為n-1;(假設數組長度為n)。

現在暫時將這三個變量分別稱為n1,n2,n1;

其中n1=n2=0,n3=n-1;

我們我們用n1從頭開始判斷,如果為1的話,那么將n1,n2換位,同時n1,n2均向后移動一個單位(后面表示換位的均為其下標在數組中對應的元素換位。)

如果為2的話n1向后移動一位,n2不變。

如果是3的話,將n1和n3換位,同時n3向前移動一位,n1不變。

直至n1=n3時,說明排列完成。下面就是輸出的問題了

怎么輸出這里就不用多說了吧

下面我們看代碼。

 

#include<stdio.h>
#include<stdlib.h>
void arr(int a[],int n)//重排列函數
{
int i,k,l;
int x;//定義中間變量,用於交換
i=0,k=n-1;//賦初值
l=0;
while(l<=k)//進行排列。
{
switch (a[l])
{
case /* constant-expression */1:
x=a[l];
a[l]=a[i];
a[i]=x;
i++;
l++;
/* code */
break;
case 2:
l++;
break;
case 3:
x=a[l];
a[l]=a[k];
a[k]=x;
k--;
break;
}
}
}
void Put(int a[],int n)//輸出函數
{
int i;
for(i=0;i<n;i++)
printf("%d ",a[i]);
printf("\n");
}
int main()//主函數
{
int n;//長度
printf("請輸入長度\n");
scanf("%d",&n);
int *a=(int *)malloc(4*n);//申請內存
int i,k,l;//定義變量
int x;
for(i=0;i<n;i++)//輸入數組。
{
scanf("%d",&a[i]);
}
arr(a,n);//排列
Put(a,n);//輸出
return 0;
}
 
下面來看運行結果
 

 

 OK,

如果這篇博客里面有什么問題的話,還希望大家能夠給我提出來,大家共同學習,一起進步。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM