ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • SWEA 5653번: [모의 SW 역량테스트] 줄기세포 배양하기
    Problem Solving/SWEA 2020. 4. 22. 17:24

    https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWXRJ8EKe48DFAUo

     

    SW Expert Academy

    SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

    swexpertacademy.com

    모의 역량테스트 중 하나인 줄기세포 배양하기 문제!!

    요즘 출제되는 전형적인 시뮬레이션 문제이당(이동, 번식, 등등 시간 경과 후 결과)

     

    세포 번식

    생명력 X를 가진 비활성 세포는 X시간 후 활성 세포가 되고

    활성 세포는 첫 1시간에 상하좌우로 번식(한 칸에 여러 세포가 시도할 경우 가장 큰 생명력을 선택),

    X시간 후에는 죽은 세포가 된다

     

    풀이 노트

    이 문제 또한 각각의 자료를 저장 및 연산할 자료구조를 잘 선택해야 한다

    나는 위의 노트처럼 문제를 보자마자 바로 #include부터 쓰면서 코딩하는 것이 아닌,

    문제를 내가 알아볼 수 있게 정리하고 내가 생각하는 알고리즘을 대략적으로 구상했다.

    이렇게 하면, 체계적으로 코딩을 할 수 있고

    어느 부분에서 막혔다면 어느 부분의 알고리즘을 구체화 해야할 지 알 수 있다.

     

    나는 노트에 정리한 내용을 바탕으로 {상태, 생명력, 시간}의 구조체 배열을 생성하고,

    활성/비활성 세포들은 좌표 구조체 형태의 큐에 저장했다

    그리고 활성상태에서 번식할 추가 세포들은 대기 큐에 미리 넣어준 다음,

    좌표가 겹치지 않게 한 세포만 비활성 세포 큐에 넣어주었다

    비활성 상태 세포들은 각각 count를 감소시켜주고 0인 세포는 활성세포 큐에 push

     

    그리고 K시간이 지난 후 활성세포 큐와 비활성세포 큐의 사이즈를 더해주면 끝!

    #include <cstdio>
    #include <queue>
    #define loc 400
    using namespace std;
    int tc, ans, n, m, k, dx[] = { 1,0,-1,0 }, dy[] = { 0,1,0,-1 };
    typedef struct {
    	int r, c;
    }point;
    typedef struct {
    	int state, X, cnt;
    }cell;
    cell map[1001][1001];
    bool visit[1001][1001];
    queue<point> A, N,W;
    int main() {
    	scanf("%d", &tc);
    	for (int T = 1; T <= tc; T++) {
    		scanf("%d%d%d", &n, &m, &k);
    		for (int i = loc; i < loc + n; i++)
    			for (int j = loc, d; j < loc + m; j++) {
    				scanf("%d", &d);
    				if (d) {
    					map[i][j] = {3,d,d};
    					N.push({ i,j });
    				}
    			}
    
    		while (k--) {	//K초동안
    			//활성세포 처리
    			int nonActsize = N.size();
    			for (int i = (int)A.size(); i >0 ; i--) {
    				point cp = A.front(); A.pop();
    				cell& cur = map[cp.r][cp.c];
    				if (cur.cnt == cur.X)
    					for (int d = 0, nx, ny; d < 4; d++) {
    						ny = cp.r + dy[d], nx = cp.c + dx[d];
    						if (!map[ny][nx].state
    							|| (map[ny][nx].state == 4
    								&& map[ny][nx].X < cur.X)) {
    							map[ny][nx] = {4,cur.X,cur.X};
    							if (!visit[ny][nx]) {
    								W.push({ ny,nx });
    								visit[ny][nx] = 1;
    							}
    						}
    					}//4방향 번식
    				cur.cnt--;	//생명력 감소
    				if (!cur.cnt)	//사망
    					cur.state = 1;
    				else A.push(cp);
    			}
    			while (!W.empty()) {
    				point cp = W.front(); W.pop();
    				cell& cur = map[cp.r][cp.c];
    				visit[cp.r][cp.c] = 0;
    				cur.state = 3;
    				N.push(cp);
    			}
    
    			for (int i = nonActsize; i >0 ; i--) {
    				point cp = N.front(); N.pop();
    				cell& cur = map[cp.r][cp.c];;
    				if (!(--cur.cnt)) {
    					cur.state = 2;
    					cur.cnt = cur.X;
    					A.push(cp);
    				}
    				else
    					N.push(cp);
    			}
    		}
    		ans = A.size() + N.size();
    
    		printf("#%d %d\n", T, ans); ans = 0;
    		while (!A.empty())A.pop();
    		while (!N.empty())N.pop();
    		for(int i=0;i<1000;i++)
    			for(int j=0;j<1000;j++)
    				if (map[i][j].state) {
    					map[i][j] = { 0,0,0 };
    				}
    
    	}
    	return 0;
    }

    모든 TC에서의 초기화에서 시간을 많이 잡아먹은 코드 😢

    큐의 연산을 할 때는 계속 변하는 size에 유의해주도록 하자

Designed by Tistory.