[CODEVS 1050] Board dyeing 2, codevs1050
Description
There is a 5 * N board, some of which have been dyed black, your task is to dye the smallest lattice, so that all the black can be connected together.
Http://codevs.cn/problem/1050/
Analysis
CODEVS has a very conscientious person in his question. I wrote it only after reading it.
Http://codevs.cn/wiki/solution? Problem_id = 1050
Solution_ID: 5329
Outline DP.
I started to put normalize (B) in front of if. As a result, if judges that soy sauce has been applied...
The four-in system (two binary bits) is used to represent the state of the contour line. 0 is a white grid, and 1, 2, and 3 are different black grids.
Main ():
If (x, y) is a black spot
If the current status is (x, y), the dots above are black spots:
Obtain the ID of the strongly connected component and set the current grid to the same strongly connected component number.
In else if current status (x, y), the point on the left of "y> 0" is black:
Obtain the ID of the strongly connected component and set the current grid to the same strongly connected component number.
Else: as a separate strong Unicom component (numbered 3 ).
Else:
1. Add directly without modification
2. Change to 1 =>
If the current status is (x, y), the dots above are black spots:
Obtain the ID of the strongly connected component and set the current grid to the same strongly connected component number.
Else if current status (x, y), y> 0 & the point on the left is a black spot:
Obtain the ID of the strongly connected component and set the current grid to the same strongly connected component number.
Else: as a separate strong Unicom component
What is the difference between the result after & 3 of a and B? => Two adjacent grids => since the adjacent grids are both black, they should belong to a strong Unicom Component => merge the two strong Unicom components.
This is a bit messy =
The grid in the upper-left corner of the current grid will exit the contour line. If it disappears, its strong Unicom component may disappear, resulting in a new redundant strong Unicom component.
=>
If the grid in the upper-left corner is not empty, and B does not have a grid with the same strong Unicom component number as B, it indicates that B is invalid and cannot update the answer.
If there is no grid first numbered 1 in the contour line, the grid behind it cannot be connected with the grid above it, nor is it legal.
The answer can be updated after several requirements are met.
Bitwise operations used
Code
127 ms KB
Simplified the code.
I checked the code highlight and found that the state and read seem to be reserved words. I don't need them anymore...
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn = 100 + 10;int cur, board[maxn][5], f[2][1<<15];bool appear;void merge(int& state, int a, int b) { for(int i = 0; i < 12; i+=2) if(((state>>i) & 3) == a) state = state ^ (a<<i) ^ (b<<i);}bool exist(int state, int color) { for(int i = 0; i < 10; i+=2) if(((state>>i) & 3) == color) return 1; return 0;}void normalize(int& state) { if(!exist(state, 2) && exist(state, 3)) { if(appear) merge(state, 3, 2); else { merge(state, 3, 1); appear = 1; } }}void update(int a, int b, int row, int col) { if((a&3) > 0 && (b&3) > 0 && col > 0 && (a&3) != (b&3)) merge(b, max(a&3, b&3), min(a&3, b&3)); if(a == 0 || (((b>>10) <= 0 || exist(b, b>>10)) && (((b>>10) == 1) || exist(b, 1)))) { normalize(b); int t = (board[row][col] == 1 || (b&3) == 0) ? 0 : 1; b ^= (b>>10) << 10; f[cur][b] = min(f[cur][b], f[1-cur][a] + t); }}int main() { int n, lasti = 0, lastj = 0; scanf("%d", &n); for(int i = 0; i < n; i++) { char read[5]; scanf("%s", read); for(int j = 0; j < 5; j++) { board[i][j] = read[j] - '0'; if(board[i][j]) { lasti = i; lastj = j; } } } memset(f, 0x7f, sizeof(f)); f[cur][0] = 0; for(int i = 0; i < n; i++) if(i <= lasti) for(int j = 0; j < 5; j++) { if(!board[i][j] && !appear) continue; if(i == lasti && j > lastj) break; cur ^= 1; memset(f[cur], 0x7f, sizeof(f[cur])); for(int k = 0; k < (1<<10); k++) { if((k>>8) > 0) update(k, (k<<2)^(k>>8), i, j); else if((k&3) > 0 && j) update(k, (k<<2)^(k&3), i, j); else update(k, (k<<2)^3, i, j); // new color if(!board[i][j]) update(k, k<<2, i, j); } } int ans = 0x7fffffff; for(int state = 0; state < (1<<10)-1; state++) if(!exist(state, 2) && !exist(state, 3)) ans = min(ans, f[cur][state]); printf("%d\n", ans); return 0;}