問題描述 參考
有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...