ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준 25598] Alive or Dead?
    C 프로그래밍/BOJ 2022. 12. 5. 16:28
    728x90

    인덱스 몇 까지 놓아야 하는지 모르겠으면 벡터써라 구조체 쓰고싶으면 생각을 해라 제발

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

     

    25598번: Alive or Dead?

    <초기 게임 필드> 파란색 원, 회색 사각형, 초록색 삼각형, 노란색 삼각형은 각각 플레이어, 벽, 하급 좀비, 상급 좀비를 의미한다. 좀비의 경우 삼각형의 방향이 좀비의 이동 방향을 의미하며, 삼

    www.acmicpc.net

    #include <cstdio>
    #include <cstring>
    #include <vector>
    int N;
    char CMD[10000 + 2];
    int px, py;
    
    int W;
    int wall[25 + 2][25 + 2];
    int Z;
    
    struct _st
    {
    	int x, y;
    	int type;
    	char dir;
    	int speed;
    };
    _st ZOMBI[625 + 2];
    int zpos[25 + 2][25 + 2];
    int D;
    int dead_day;
    
    
    // dir
    // 상 우 하 좌
    int dir_x[4] = { -1, 0, 1, 0 };
    int dir_y[4] = { 0, 1, 0, -1 };
    int dir_op[4] = { 2, 3, 0, 1 };
    
    
    void input()
    {
    	scanf("%d", &N);
    	scanf("%s", &CMD);
    	scanf("%d %d", &px, &py);
    	scanf("%d", &W);
    	for (int i = 0; i < W; i++) {
    		int wx = 0, wy = 0;
    		scanf("%d %d", &wx, &wy);
    		wall[wx][wy] = 1;
    	}
    	scanf("%d", &Z);
    	for (int i = 1; i <= Z; i++) {	// 사실 이거 처음에 숫자로 바꿔주면 char -> int, int -> char 할 필요 없음 
    		scanf("%d %d %d %c %d", &ZOMBI[i].x, &ZOMBI[i].y, &ZOMBI[i].type, &ZOMBI[i].dir, &ZOMBI[i].speed);
    	}
    	scanf("%d", &D);
    }
    
    void move_player(char dir)
    {
    	int ndir = -1; 
    
    	if (dir == 'U') ndir = 0;
    	else if (dir == 'R') ndir = 1;
    	else if (dir == 'D') ndir = 2;
    	else if (dir == 'L') ndir = 3;
    	else if (dir == 'S') return;	// 제자리, 이동하지 않음
    
    	int nx = px + dir_x[ndir];
    	int ny = py + dir_y[ndir];
    	if (nx < 1 || nx > N || ny < 1 || ny > N || wall[nx][ny] == 1) return;	// 이동하지 않음
    	px = nx, py = ny;
    	return;
    }
    
    
    int cnt_wall(int x, int y, int p)
    {
    	int cnt = 0;
    	int nx = x;
    	int ny = y;
    
    	while (1) {
    		if (nx + dir_x[p] < 1 || nx + dir_x[p] > N || ny + dir_y[p] < 1 || ny + dir_y[p] > N) break;
    		if (wall[nx + dir_x[p]][ny + dir_y[p]] == 1) cnt++;
    		nx += dir_x[p];
    		ny += dir_y[p];
    	}
    
    	return cnt;
    }
    
    
    void move_zombies()
    {
    	// init
    	memset(zpos, 0, sizeof(zpos));
    
    	for (int i = 1; i <= Z; i++) {
    		int type = ZOMBI[i].type;
    		char dir = ZOMBI[i].dir;
    		int ndir = -1;
    		int speed = ZOMBI[i].speed;
    
    		if (dir == 'U') ndir = 0;
    		else if (dir == 'R') ndir = 1;
    		else if (dir == 'D') ndir = 2;
    		else if (dir == 'L') ndir = 3;
    
    		if (type == 0) {	// 하급좀비
    			int nx = ZOMBI[i].x;
    			int ny = ZOMBI[i].y;
    			
    			for (int s = 1; s <= speed; s++){
    				if (nx + dir_x[ndir] < 1 || nx + dir_x[ndir] > N || ny + dir_y[ndir] < 1 || ny + dir_y[ndir] > N) {
    					ndir = dir_op[ndir];
    					break;
    				}
    				if (wall[nx + dir_x[ndir]][ny + dir_y[ndir]] == 1) {
    					ndir = dir_op[ndir];
    					break;
    				}
    				nx += dir_x[ndir];
    				ny += dir_y[ndir];
    			}
    
    			if (ndir == 0) dir = 'U';
    			else if (ndir == 1) dir = 'R';
    			else if (ndir == 2) dir = 'D';
    			else if (ndir == 3) dir = 'L';
    
    			ZOMBI[i] = { nx, ny, type, dir, speed };
    			zpos[nx][ny] = 1;
    			//printf("[zom 0]%d %d %d\n", nx, ny, ndir);
    		}
    		else if (type == 1) {	// 상급좀비
    			int nx = ZOMBI[i].x;
    			int ny = ZOMBI[i].y;
    
    			// 이동하기
    			for (int h = 1; h <= speed; h++) {
    				if (nx + dir_x[ndir] < 1 || nx + dir_x[ndir] > N || ny + dir_y[ndir] < 1 || ny + dir_y[ndir] > N) break;
    				if (wall[nx + dir_x[ndir]][ny + dir_y[ndir]] == 1) {
    					wall[nx + dir_x[ndir]][ny + dir_y[ndir]] = 0;	// 그 앞의 벽을 부순다
    					break;
    				}
    				nx += dir_x[ndir];
    				ny += dir_y[ndir];
    			}
    			// 방향 틀기
    			int max_cnt = -1;
    			int opt_dir = -1;
    			for (int p = 0; p < 4; p++) {
    				int res = cnt_wall(nx, ny, p);
    				if (res > max_cnt) {
    					max_cnt = res;
    					opt_dir = p;
    				}
    			}
    
    			char nopt_dir = '-1';
    			if (opt_dir == 0) nopt_dir = 'U';
    			else if (opt_dir == 1) nopt_dir = 'R';
    			else if (opt_dir == 2) nopt_dir = 'D';
    			else if (opt_dir == 3) nopt_dir = 'L';
    
    
    			ZOMBI[i] = { nx, ny, type, nopt_dir, speed };
    			zpos[nx][ny] = 1;
    			//printf("[zom 1]%d %d %d\n", nx, ny, opt_dir);
    		}
    	}
    }
    
    
    
    
    
    
    bool simulation()
    {
    	for (int day = 1; day <= D; day++) {
    		if (CMD[day - 1] == '\0') break;
    		move_player(CMD[day - 1]);
    		//printf("%d %d %c\n", px, py, CMD[day - 1]);
    		move_zombies();
    		if (zpos[px][py] == 1) {
    			dead_day = day;
    			return false;	// 좀비와 플레이어가 같은 칸에 있는 경우 
    		}
    	}
    	return true;
    }
    
    
    int main()
    {
    	input();
    	bool res = simulation();
    	if (res == false) {
    		printf("%d\n", dead_day);
    		printf("DEAD...\n");
    	}
    	else printf("ALIVE!\n");
    	return 0;
    }

    딱히 깔끔한 코드는 아닌 것 같다. 

    좀비 방향 처음에 입력받을 때 바꿔주고 그 다음 부터는 char 필요없이 int로만 움직이면 되기 때문이다.. 

     

    마지막에 좀비와 플레이어의 위치가 겹치는지 확인해줄 때는 zpos라는 이차원 배열에 좀비가 이동한 후의 위치를 표시해주고, 플레이어의 위치를 zpos에서 찾았을 때 1이면(좀비가 위치해 있으면) 죽이도록 구현했다. 

     

    728x90

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

    [백준 1261] 알고스팟  (0) 2022.12.06
    [백준 1941] 소문난 칠공주  (0) 2022.12.06
    [백준 6987] 월드컵  (0) 2022.12.01
    [백준 3055] 탈출  (0) 2022.11.30
    [백준 15683] 감시  (0) 2022.11.29

    댓글

Designed by Tistory.