1
+ // https://leetcode.com/contest/biweekly-contest-35/problems/strange-printer-ii/
2
+ //
3
+ // #biweekly 35
4
+ // #6, #topological order, #greedy, #like
5
+
6
+ // Given a [m x n] matrix, the grid value means color.
7
+ //
8
+ // Each turn, we can print a solid rectangular of a color in the matrix.
9
+ // The same color cannot be used again.
10
+ //
11
+ // Given a [m x n] matrix targetGrid, return true if it doesn't volatile the
12
+ // above rule, else return false.
13
+ #include " std.h"
14
+
15
+ enum {
16
+ UNINIT,
17
+ VISITED,
18
+ CHECKED,
19
+ };
20
+ bool dfsHasLoop (const unordered_set<int > edges[61 ], vector<int > &state,
21
+ int color) {
22
+ state[color] = VISITED;
23
+ for (int v : edges[color]) {
24
+ if (state[v] == CHECKED)
25
+ continue ;
26
+ if (state[v] == VISITED)
27
+ return true ;
28
+ if (dfsHasLoop (edges, state, v))
29
+ return true ;
30
+ }
31
+ state[color] = CHECKED;
32
+ return false ;
33
+ }
34
+
35
+ bool isPrintable (vector<vector<int >> &targetGrid) {
36
+ const int m = targetGrid.size (), n = targetGrid[0 ].size ();
37
+ unordered_set<int > edges[61 ];
38
+ // greedy, O(CMN)
39
+ for (int color = 1 ; color <= 60 ; ++color) {
40
+ int top = m, left = n, right = 0 , bottom = 0 ;
41
+ for (int i = 0 ; i < m; ++i)
42
+ for (int j = 0 ; j < n; ++j)
43
+ if (color == targetGrid[i][j]) {
44
+ top = min (top, i);
45
+ left = min (left, j);
46
+ right = max (right, j);
47
+ bottom = max (bottom, i);
48
+ }
49
+
50
+ // find overlapped grid
51
+ for (int i = top; i <= bottom; ++i)
52
+ for (int j = left; j <= right; ++j)
53
+ if (color != targetGrid[i][j])
54
+ edges[color].insert (targetGrid[i][j]);
55
+ }
56
+
57
+ // dfs check loop
58
+ vector<int > state (61 );
59
+ for (int color = 1 ; color <= 60 ; ++color)
60
+ if (dfsHasLoop (edges, state, color))
61
+ return false ;
62
+ return true ;
63
+ }
0 commit comments