Stem Cell Culture July 18, 2019 https://www.swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWXRJ8EKe48DFAUo Source explicit CProbSolve(const int N, const int M, const int K) { (void)memset(&(g_arMap[0][0]), 0, sizeof(g_arMap)); m_initRowsN = N; m_initColsM = M; m_timeLimitK = K; m_mapMaxRows = INIT_MAP_OFFSET + m_initRowsN + INIT_MAP_OFFSET; m_mapMaxCols = INIT_MAP_OFFSET + m_initColsM + INIT_MAP_OFFSET; m_mapRowRange.first = m_mapMaxRows; m_mapRowRange.second = 0; m_mapColRange.first = m_mapMaxCols; m_mapColRange.second = 0; FOR(row, m_initRowsN) { FOR(col, m_initColsM) { int val = 0; cin >> val; if (val > 0) { g_arMap[0][row + INIT_MAP_OFFSET][col + INIT_MAP_OFFSET] = val; g_arMap[1][row + INIT_MAP_OFFSET][col + INIT_MAP_OFFSET] = val; _UpdateRange(row + INIT_MAP_OFFSET, col + INIT_MAP_OFFSET); } } } _Solve(); } void _BFSwithGenerations() { queue<i_ii> arqLifePos[2]; FOR_INC(row, m_mapRowRange.first, m_mapRowRange.second + 1) { FOR_INC(col, m_mapColRange.first, m_mapColRange.second + 1) { const int val = g_arMap[0][row][col]; if (val > 0) { arqLifePos[0].push(i_ii(2 * val, (ii(row, col)))); } } } // repeat the loop until time limit vector<i_ii> vPrevExtendedCells; FOR(gen, m_timeLimitK) { const int i = gen % 2; const int ni = (gen + 1) % 2; if (!vPrevExtendedCells.empty()) { // update the map and the queue with previously extended cells _UpdateMapAndQueue(vPrevExtendedCells, arqLifePos[i]); } // visit all the stem cells in the current queue while (!arqLifePos[i].empty()) { const i_ii life_pos = arqLifePos[i].front(); arqLifePos[i].pop(); const int row = life_pos.second.first; const int col = life_pos.second.second; // getting old const int life = life_pos.first - 1; if (life <= 0) { // dies g_arMap[0][row][col] = -1; continue; } // still alive: push into the next queue arqLifePos[ni].push(i_ii(life, ii(row, col))); const int val = g_arMap[0][row][col]; if (life > val) continue; // now active! // for extention, the map is going to be updated in the next loop FOR(dir, eDIR_LEN) { const int nextRow = row + DIR[dir][0]; const int nextCol = col + DIR[dir][1]; P_IFNOT(!OOR(nextRow, 0, m_mapMaxRows - 1), nextRow); P_IFNOT(!OOR(nextCol, 0, m_mapMaxCols - 1), nextCol); if (g_arMap[0][nextRow][nextCol] != 0) continue; // previously empty cell if (val > g_arMap[1][nextRow][nextCol]) { g_arMap[1][nextRow][nextCol] = val; _UpdateRange(nextRow, nextCol); // extention candidates which will get old from the next after the next generation vPrevExtendedCells.push_back(i_ii((2 * val) + 1, ii(nextRow, nextCol))); } } } // while (!m_arqLifePos[i].empty()) } // FOR(gen, m_timeLimitK) } void _UpdateMapAndQueue(vector<i_ii> &vPrevExtendedCellsOut, queue<i_ii> &qLifePosOut) { while (!vPrevExtendedCellsOut.empty()) { const i_ii life_pos = vPrevExtendedCellsOut.back(); vPrevExtendedCellsOut.pop_back(); const int row = life_pos.second.first; const int col = life_pos.second.second; const int val = g_arMap[1][row][col]; if (life_pos.first == (2 * val) + 1) { // resultant extentions g_arMap[0][row][col] = val; // it start to get old from the next generation qLifePosOut.push(life_pos); } } } Source with respective queues for each life time #pragma GCC optimize("O3") #include <iostream> #include <algorithm> #include <memory.h> using namespace std; #define BASE 151 struct p { int r, x, y; }; int map[360][360]; p q[11][2][2001]; // life time, switching by 2, cell of each life time int main() { ios::sync_with_stdio(false); cin.tie(0); register int t, tc, N, M, K, s, dx[] = { 0,0,1,-1 }, dy[] = { 1,-1,0,0 }, idx[11][2] = { 0, }; cin >> t; for (tc = 1; tc <= t; ++tc) { register int i, j, k, l, nx, ny, ans, siz, ni, tt; memset(map, 0, sizeof(map)); memset(idx, 0, sizeof(idx)); cin >> N >> M >> K; ans = 0; for (i = 0; i < N; ++i) for (j = 0; j < M; ++j) { nx = i + BASE; ny = j + BASE; cin >> tt; if (tt) q[tt][0][idx[tt][0]++] = { 2 * tt, nx, ny }; map[nx][ny] = tt; } s = 0; // for generations for (i = 0; i <= K; ++i) { // for each life time for (j = 10; j >= 1; --j) { siz = idx[j][i % 2]; ni = (i + 1) % 2; idx[j][ni] = 0; // for each cell of each life time for (k = 0; k < siz; ++k) { p &x = q[j][i%2][k]; if (x.r > j) { if (map[x.x][x.y] > 0) { ans++; map[x.x][x.y] *= -1; } q[j][ni][idx[j][ni]++] = { x.r - 1,x.x,x.y }; } else if (x.r == j) { q[j][ni][idx[j][ni]++] = { x.r - 1,x.x,x.y }; for (l = 0; l < 4; ++l) { nx = x.x + dx[l]; ny = x.y + dy[l]; if (map[nx][ny]) continue; map[nx][ny] = j; q[j][ni][idx[j][ni]++] = { 2 * j,nx,ny }; } } else if (j > x.r && x.r) q[j][ni][idx[j][ni]++] = { x.r - 1,x.x,x.y }; else ans--; } } } cout << '#' << tc << ' ' << ans << '\n'; } return 0; } GitHub StemCellCulture Share Share on Facebook Tweet Share on Reddit Email Tags bfs-with-generations cpp simple-implementation std-queue