題目描述:
水叮噹得到了一塊五顏六色的格仔形地毯作為生日禮物,更加特別的是,地毯上格仔的顏色還能隨著踩踏而改變。
為了討好她的偶像虹貓,水叮噹決定在地毯上跳一支輕盈的舞來賣萌~~~
地毯上的格仔有n行n列,每個格仔用乙個0~5之間的數字代表它的顏色。
水叮噹可以隨意選擇乙個0~5之間的顏色,然後輕輕地跳動一步,左上角的格仔所在的聯通塊裡的所有格仔就會變成她選擇的那種顏色。這裡連通定義為:兩個格仔有公共邊,並且顏色相同。
由於水叮噹是施展輕功來跳舞的,為了不消耗過多的真氣,她想知道最少要多少步才能把所有格仔的顏色變成一樣的。
輸入描述:
每個測試點包含多組資料。
每組資料的第一行是乙個整數n,表示地攤上的格仔有n行n列。
接下來乙個n*n的矩陣,矩陣中的每個數都在0~5之間,描述了每個格仔的顏色。
n=0代表輸入的結束。
輸出描述:
對於每組資料,輸出乙個整數,表示最少步數。
樣例輸入:
2 0 0
0 0
3 0 1 2
1 1 2
2 2 1
0樣例輸出:
對於30%的資料,n<=5
對於50%的資料,n<=6
對於70%的資料,n<=7
對於100%的資料,n<=8,每個測試點不多於20組資料。
第二組樣例解釋:
0 1 2 |1 1 2|2 2 2|1 1 1|
1 1 2 |1 1 2|2 2 2|1 1 1|
2 2 1 |2 2 1|2 2 1|1 1 1|
思路:
迭代搜尋+a*搜尋
迭代加深的搜尋思想:
每次進行深搜限制搜尋步數,若是搜尋實際步驟和當前答案深度估計值之和大於了限制步數,就直接跳出搜尋過程,用這樣的方法來加快搜尋速度。
a*的搜尋思想:
給每一步搜尋加乙個答案深度的估計值,並與當前使用的步數結合,來判斷是否需要走該步(簡單來說,就是判斷搜尋的方向)。乙個優質的估價函式可以極大程度的加快答案的計算速度。
解題的方法很簡單,每次讀入資料後重新建造乙個優化圖:該圖形式和讀入的圖相同,不過是用1標記與左上角點在同一聯通塊(同一種顏色)的點,用2標記在該聯通塊外邊界上的點,其餘點用0來標記。這樣可以大幅度減少尋找聯通塊的時間和更新的時間。
然後進行限制深度的迭代加深搜尋,列舉深度進入搜尋:
每次對當前狀態進行搜尋,先用a*對該點進行估價,估價值為剩下的顏色數,該估價值與當前步數相加若是大於了深度限制則返回false。而當估價值為0時,即返回true,說明找到了答案。
在每次搜尋中,列舉當前選擇的顏色,並對聯通塊進行塗色並擴充套件,如果擴充套件後並沒有增加它的大小,則說明這次塗色是不必要的,就列舉下乙個顏色。
#include
#include
using
namespace
std;
int n,ans;//ans是迭代搜尋時的限制,也是最終的答案
intmap[10][10],flag[9][9];
bool hash[10];//估價函式中用來判重
int xx[5]=,
yy[5]=;
int compute()//估價函式,獲得估價值
return tmp;
}void dfs(int x,int y,int col)//對聯通塊進行擴充套件,col標記當前染的顏色
}}int judge(int col)//該次染色對聯通塊大小有無影響的判斷函式
return tmp;
}bool a_star(int deep)//a*搜尋
return
0;//以上條件都不滿足,返回假
}int main()
return
0;}
水叮噹的舞步 深搜
背景background 水叮噹得到了一塊五顏六色的格仔形地毯作為生日禮物,更加特別的是,地毯上格仔的顏色還能隨著踩踏而改變。為了討好她的偶像虹貓,水叮噹決定在地毯上跳一支輕盈的舞來賣萌 描述description 地毯上的格仔有n行n列,每個格仔用乙個0 5之間的數字代表它的顏色。水叮噹可以隨意選...
JZOJ 3422 水叮噹的舞步
水叮噹得到了一塊五顏六色的格仔形地毯作為生日禮物,更加特別的是,地毯上格仔的顏色還能隨著踩踏而改變。為了討好她的偶像虹貓,水叮噹決定在地毯上跳一支輕盈的舞來賣萌 地毯上的格仔有n行n列,每個格仔用乙個0 5之間的數字代表它的顏色。水叮噹可以隨意選擇乙個0 5之間的顏色,然後輕輕地跳動一步,地毯左上角...
BZOJ T3041 水叮噹的舞步
bzoj 3041 水叮噹的舞步 這是道ida 迭代加深 估價剪枝 首先考慮估價函式,一般情況下我們把易於計算的操作次數的下限作為a 的估價函式,易知這道題裡每次有效操作只會向外拓寬乙個顏色層,那麼估價函式就可以確定為剩下未被拓展的顏色層數。這個層數就是答案,這個數的下限就是剩餘未探索的顏色數,道理...