ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준 20055] 컨베이어 벨트 위의 로봇
    C 프로그래밍/BOJ 2022. 9. 29. 01:38
    728x90

    https://www.acmicpc.net/problem/20055

     

    20055번: 컨베이어 벨트 위의 로봇

    길이가 N인 컨베이어 벨트가 있고, 길이가 2N인 벨트가 이 컨베이어 벨트를 위아래로 감싸며 돌고 있다. 벨트는 길이 1 간격으로 2N개의 칸으로 나뉘어져 있으며, 각 칸에는 아래 그림과 같이 1부

    www.acmicpc.net

    #include <cstdio>
    int N, K;
    struct _st
    {
    	int w;	// 내구도
    	int robot;	// 로봇있으면 1 없으면 0
    }Belt[200 + 2];
    
    
    void input()
    {
    	scanf("%d %d", &N, &K);
    	for (int i = 0; i < 2 * N; i++) {
    		scanf("%d", &Belt[i].w);
    	}
    }
    
    void debug()
    {
    	for (int i = 0; i < 2 * N; i++) {
    		printf("[번호] %d [내구도]%d [로봇존재]%d\n", i, Belt[i].w, Belt[i].robot);
    	}
    }
    
    
    
    int simul()
    {
    	int step = 0;
    	while (1) {
    		int tmp_w = Belt[2 * N - 1].w;
    		int tmp_r = Belt[2 * N - 1].robot;
    
    		for (int i = 2 * N - 1; i >= 1; i--) {
    			Belt[i].w = Belt[i - 1].w;
    			Belt[i].robot = Belt[i - 1].robot;
    			if (i == N - 1) Belt[i].robot = 0;	// 내리는 칸이라면 로봇 즉시 내림 
    		}
    		Belt[0].w = tmp_w;
    		Belt[0].robot = tmp_r;
    		
    		// 2번
    		for (int i = 2 * N - 1; i >= 0; i--) {
    			if (Belt[i].robot == 0) continue;	// 해당 칸에 로봇이 없다면 스루 
    			if (Belt[(i + 1) % (2 * N)].robot == 0 && Belt[(i + 1) % (2 * N)].w >= 1) {	// 이동할 칸에 로봇이 존재하지 않고 가중치가 1 이상일 때 
    				Belt[i].robot = 0;
    				Belt[(i + 1) % (2 * N)].robot = 1;	// 해당 칸으로 로봇 이동 
    				Belt[(i + 1) % (2 * N)].w -= 1;		// 해당 칸 내구도 1 감소
    			}
    			if (((i + 1) % (2 * N)) == N - 1) Belt[N - 1].robot = 0;	// 내리는 칸이라면 로봇 즉시 내림 
    		}
    
    		// 3번 
    		if (Belt[0].w != 0) {
    			Belt[0].robot = 1;
    			Belt[0].w -= 1;
    		}
    
    		// 4번
    		int cnt = 0;
    		for (int i = 0; i < 2 * N; i++) {
    			if (Belt[i].w == 0) cnt++;
    		}
    		step++;
    		if (cnt >= K) return step;	// 그냥 문제 말 듣자 ... ^^ 내구도가 0인 칸의 개수가 K개 "이상" 이라잖아... 
    	}
    	return -1;
    }
    
    
    int main()
    {
    	input();
    	int ans = simul();
    	printf("%d\n", ans);
    	return 0;
    }

    코드 짜는 것 보다 문제 이해하는데 시간을 더 많이 쓴듯.. ㅋㅋ... 

    하지만 나레기 장하다. 한달 전에는 무서워서 손도 못댔는데 ㅎㅋ.. 

     

    같이 공부하는 사람들 중에는 deque 쓴 사람이 많던데... 저는 무식해서 그런거 잘 못쓰고 구조체로 조졋슴 ㅋ

    미리 밝히지만 내 코드는 실행시간이 128ms나 된다. 좋은 코드는 아니다.. ㅎ

     

     

    // simul ( ) 함수

    문제가 하라는대로 하면 된다. 

    (1) 벨트가 각 칸 위에 있는 로봇과 함께 한 칸 회전한다. 

        => 이를 구현하기 위해 루프를 돌려서 i -1 번째 칸의 정보를 i번째 칸으로 밀어주었다. 그러면 가장 마지막 칸의 정보는 0번째 칸으로 올려야 하는데, 이를 위해 루프를 돌리기 전에 tmp_w, tmp_r에 해당 정보들을 저장하고 이를 루프를 돌린 후 0번째 칸의 구조체에 저장해주었다. 

    이때 주의해야 할 점은 이렇게 칸을 이동한 결과 로봇이 N번 위치(내리는 위치)에 도달하면 그 즉시 내려야 한다. 해당 조건을 반드시 기재해야 한다. 

     

    (2) 가장 먼저 벨트에 올라간 로봇부터, 벨트가 회전하는 방향으로 한 칸 이동할 수 있다면 이동한다. 만약 이동할 수 없다면 가만히 있는다. 

    단, 로봇이 이동하기 위해서는 이동하려는 칸에 로봇이 없으며, 그 칸의 내구도가 1 이상 남아있어야 한다. 

        => 이것도 그냥 루프 돌려서 해결했다. 다만, "가장 먼저 벨트에 올라간 로봇"이라고 하였으므로 이번에도 인덱스를 2 * N - 1 부터 시작하였다. 올리는 곳과 떨어져있으면 떨어져 있을수록 일찍 올린 로봇일 것이기 때문이다. 

    이때도 주의해야 할 점은 이렇게 칸을 이동한 결과 로봇이 N번 위치(내리는 위치)에 도달하면 그 즉시 내려야 한다. 해당 조건을 반드시 기재해야 한다. 

     

    (3) 올리는 위치에 있는 칸의 내구도가 0이 아니면 올리는 위치에 로봇을 올린다. 

        => 로봇 올리고 내구도 1 감소시키면 된다. 

     

    (4) 내구도가 0인 칸의 개수가 K개 이상이라면 과정을 종료한다. 그렇지 않다면 1번으로 돌아간다. 

        => 무식하게 루프 돌리면서 내구도가 0인 칸 세어줬다. 

    여기서 조건문 if(cnt >= K) 해줄때, 처음에 == 으로 제출하였더니 시간초과가 났다. ... 이유는 잘 모르겠... 그냥 문제가 하라는 대로 해야겠다. 

    728x90

    'C 프로그래밍 > BOJ' 카테고리의 다른 글

    [백준 5926] Cow Lineup  (0) 2022.09.29
    [백준 3967] 매직 스타  (0) 2022.09.29
    [백준 18808] 스티커 붙이기  (0) 2022.09.28
    [백준 3055] 탈출  (0) 2022.09.28
    [백준 11559] 뿌요뿌요  (0) 2022.09.28

    댓글

Designed by Tistory.