撥鐘問題的若干解法

2021-07-09 03:19:26 字數 2791 閱讀 1307

問題描述  參考

有9個時鐘,排成乙個3*3的矩陣。現在需要用最少的移動,將9個時鐘的指標都撥到12點的位置。共允許有9種不同的移動。如右表所示,每個移動會將若干個時鐘的指標沿順時針方向撥動90度。

移動 影響的時鐘

1 abde

2 abc

3 bcef

4 adg

5 bdefh

6 cfi

7 degh

8 ghi

9 efhi

輸入從標準輸入裝置讀入9個整數,表示各時鐘指標的起始位置。0=12點、1=3點、2=6點、3=9點。

輸出輸出乙個最短的移動序列,使得9個時鐘的指標都指向12點。按照移動的序號大小,輸出結果。

樣例輸入

3 3 0

2 2 2

2 1 2

樣例輸出

4 5 8 9

假設時鐘指標位置對應的值為clock_time,那麼順時針旋轉90°就是clock_time = (clock_time+1)%4這一組時針就用乙個陣列表示。9種操作對應乙個二維陣列。這一題實質類似熄燈問題和畫家問題。其共通點在於:操作對環境的改變是無序的,每個操作都會影響到周圍的狀態。同時每一種操作都有週期性限制,也即最多需要幾次操作,多於這個次數產生迴圈。熄燈問題中,每個燈最多熄燈一次,因為燈只有兩種狀態,並且迴圈。而這裡,有4種迴圈的狀態,因此每個移動操作頂多使用3次。我們對移動方法1,2,3進行列舉,每種方法無非實施0-3次,也即一共4^3=64種情況。這些情況之間並非沒有關係。例如,我們確定了1,2,3的情況數,那麼得到乙個燈a,b,c的狀態,而只有移動4能夠改變a,移動5能夠改變b,移動6能夠改變c,那麼移動4-6的次數也確定了。同樣,這時只有移動7能夠改變d,移動9能夠改變f,這時移動7和9的次數也確定了。最後,時鐘a,b,c,d,f都已經到達12點,e,g,h,i還沒確定,只剩下移動8能夠改變ghi,所以只要檢查e是否已經到達12點以及,ghi的時鐘數是否相等就行了。最後找到乙個移動次數最小的情況。

這題也可以用暴力搜尋,因為最多有4^9個組合,不會超時。

這題還可以列出乙個方程組,九個未知數,通過高斯消元法來解方程組。

(一開始用列舉法寫了,至於上面的這種方法,稍後再補上吧)

/暴力列舉方法

**:

#include#includeusing namespace std;

int main()

; for (int i = 0; i < 9; i++)

cin>>station[i];

int move_count[9] = ;

int min_count = 10000;

for (int i1 = 0; i1 < 4; i1++)

for (int i2 = 0; i2 < 4; i2++)

for (int i3 = 0; i3 < 4; i3++)

for (int i4 = 0; i4 < 4; i4++)

for (int i5 = 0; i5 < 4; i5++)

for (int i6 = 0; i6 < 4; i6++)

for (int i7 = 0; i7 < 4; i7++)

for (int i8 = 0; i8 < 4; i8++)

for (int i9 = 0; i9 < 4; i9++)}}

int cur = 0;

for (cur = 0; cur < 9; cur++)

while (move_count[cur]--)

cout<

//撥鐘問題 

#include"stdafx.h"

#include#includeusing namespace std;

//鐘錶輸入

int clock[3][3]=;

int mainroot[9]=;//當前的最短路徑

void isok(const int i1,const int i2 ,const int i3);//如果驗證成功 那麼返回1 否則返回0

void enumerate()//將前3行的撥鐘數目進行列舉 返回列舉方法 迴圈寫在這裡面

i2++;

} i3++;

} return ;//結果存在mainroot中 }

/* 1 abde

2 abc

3 bcef

4 adg

5 bdefh

6 cfi

7 degh

8 ghi

9 efhi

*/void isok(const int i1,const int i2 ,const int i3)//如果驗證成功 那麼返回1 否則返回0

; int sum=(mainroot[1]+mainroot[2]+mainroot[3]+mainroot[4]+mainroot[5]+mainroot[6]+mainroot[7]+mainroot[8]+mainroot[0]);

if((i1+i2+i3+i4+i5+i6+i7+i8+i9)return;

} else//不符合要求 直接return繼續尋找

}return ;

}int main()

cout<} enumerate();//將前3行的撥鐘數目進行列舉 返回列舉方法

for(int i=0;i<9;i++)

return 0;

}

C語言 撥鐘問題的兩種解法。

撥鐘問題 描述有9個時鐘排成乙個3 3的矩陣,從上到下從左到右依次標為abcdefghi。每個時鐘只有1個時針,時針初始指向3 6 9或12點。對每乙個時鐘的時針共允許有9種不同的移動,每個移動會將若干個時鐘的指標沿順時針方向撥動90度。移動 影響的時鐘 1 abde 2 abc 3 bcef 4 ...

列舉 撥鐘問題

演算法思路 假設時鐘指標位置對應的值為clock time,那麼順時針旋轉90 就是clock time clock time 1 4 這一組時針就用乙個陣列表示。9種操作對應乙個二維陣列。這一題實質類似熄燈問題和畫家問題。其共通點在於 操作對環境的改變是無序的,每個操作都會影響到周圍的狀態。同時每...

貪心列舉 撥鐘問題

問題描述 有9個時鐘,排成乙個3 3的矩陣。現在需要用最少的移動,將9個時鐘的指標都撥到12點的位置。共允許有9種不同的移動。如右表所示,每個移動會將若干個時鐘的指標沿順時針方向撥動90度。移動 影響的時鐘 1 abde 2 abc 3 bcef 4 adg 5 bdefh 6 cfi 7 degh...