[codevs2495]水叮噹的舞步
試題描述
水叮噹得到了一塊五顏六色的格仔形地毯作為生日禮物,更加特別的是,地毯上格仔的顏色還能隨著踩踏而改變。
為了討好她的偶像虹貓,水叮噹決定在地毯上跳一支輕盈的舞來賣萌~~~
地毯上的格仔有n行n列,每個格仔用乙個0~5之間的數字代表它的顏色。
水叮噹可以隨意選擇乙個0~5之間的顏色,然後輕輕地跳動一步,左上角的格仔所在的聯通塊裡的所有格仔就會變成她選擇的那種顏色。這裡連通定義為:兩個格仔有公共邊,並且顏色相同。
由於水叮噹是施展輕功來跳舞的,為了不消耗過多的真氣,她想知道最少要多少步才能把所有格仔的顏色變成一樣的。
輸入
每個測試點包含多組資料。
每組資料的第一行是乙個整數n,表示地攤上的格仔有n行n列。
接下來乙個n*n的矩陣,矩陣中的每個數都在0~5之間,描述了每個格仔的顏色。
n=0代表輸入的結束。
輸出
對於每組資料,輸出乙個整數,表示最少步數。
輸入示例
2000030
1211
2221
0
輸出示例
03
資料規模及約定
對於30%的資料,n<=5
對於50%的資料,n<=6
對於70%的資料,n<=7
對於100%的資料,n<=8,每個測試點不多於20組資料。
題解
依然是迭代加深搜尋。
但是需要幾個優化。
我先貼乙份 t 的**上來:
#include #include #include #include #include #include #include #include #include #include #include using namespace std;int read()
while(isdigit(c))
return x * f;
}#define maxn 10
int n, a[maxn][maxn];
struct point
point(int _, int __): x(_), y(__) {}
} q[maxn*maxn];
int hd, tl, dx[4] = , dy[4] = ;
bool vis[maxn][maxn], get[maxn];
bool isin(int x, int y)
void bfs()
} }return ;
}void print()
bool dfs(int cur, int k)
if(!ok) break;
}// printf("%d(%d):\n", cur, k); print();
if(ok) return printf("%d\n", k), 1;
if(cur == k) return 0;
// printf("%d(%d):\n", cur, k); print();
int b[maxn][maxn];
bool vis[maxn][maxn], get[maxn];
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++) b[i][j] = a[i][j];
bfs();
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++) vis[i][j] = vis[i][j];
for(int i = 0; i <= 5; i++) get[i] = get[i];
for(int i = 0; i <= 5; i++) if(get[i])
return 0;
}int main()
return 0;
}
這份**中 dfs 每深入一層,就必定進行一遍 bfs,是非常耗時間的。
所以我們考慮不用 bfs,模了一下黃學長的題解後,明白了可以通過打標記的方式維護當前狀態,即:已經同色的區域用 1 做標記,同色區域周圍用 2 做標記,然後每次向外擴充套件時顯然只用考慮標 2 的部分,我們動態地更新這些標記,就不用每次都 bfs 了。
但這樣還不夠,我們需要加剪枝:最好的情況莫過於每次減少當前地圖中的一種顏色,如果「當前地圖沒標 1 的部分的顏色種類數 + 當前步數 > 迭代加深搜尋限制的步數」的話,就可以跳出了。
此外,向外擴張時,已經考慮過的顏色不必重複考慮了,這也是乙個重要的優化。
最終 ac **:
#include #include #include #include #include #include #include #include #include #include #include using namespace std;int read()
while(isdigit(c))
return x * f;
}#define maxn 10
int n, a[maxn][maxn], vis[maxn][maxn], dx[4] = , dy[4] = ;
void print()
bool isin(int x, int y)
void dfs(int x, int y, int col)
} return ;
}void mark(int col)
int cal()
bool solve(int cur, int k)
return 0;
}int main()
return 0;
}
Codevs 2495 水叮噹的舞步
時間限制 1 s 空間限制 32000 kb 題目等級 鑽石 diamond 題解檢視執行結果 水叮噹得到了一塊五顏六色的格仔形地毯作為生日禮物,更加特別的是,地毯上格仔的顏色還能隨著踩踏而改變。為了討好她的偶像虹貓,水叮噹決定在地毯上跳一支輕盈的舞來賣萌 地毯上的格仔有n行n列,每個格仔用乙個0 ...
水叮噹的舞步 深搜
背景background 水叮噹得到了一塊五顏六色的格仔形地毯作為生日禮物,更加特別的是,地毯上格仔的顏色還能隨著踩踏而改變。為了討好她的偶像虹貓,水叮噹決定在地毯上跳一支輕盈的舞來賣萌 描述description 地毯上的格仔有n行n列,每個格仔用乙個0 5之間的數字代表它的顏色。水叮噹可以隨意選...
JZOJ 3422 水叮噹的舞步
水叮噹得到了一塊五顏六色的格仔形地毯作為生日禮物,更加特別的是,地毯上格仔的顏色還能隨著踩踏而改變。為了討好她的偶像虹貓,水叮噹決定在地毯上跳一支輕盈的舞來賣萌 地毯上的格仔有n行n列,每個格仔用乙個0 5之間的數字代表它的顏色。水叮噹可以隨意選擇乙個0 5之間的顏色,然後輕輕地跳動一步,地毯左上角...