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

 

13913번: 숨바꼭질 4

수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일

www.acmicpc.net

 

 

 

 

 

#include <bits/stdc++.h>
using namespace std;
//숨바꼭질 4
int main(void) {
    queue<int> q;
    int n, m, visited[10000] = {0,}, time[10000] = {0,};
    cin >> n >> m;

    q.push(n);
    visited[n] = 1;

    while (!q.empty()) {
        int now = q.front();
        q.pop();
        if (now == m) {
            printf("%d\n", time[m]);
            break;
        }
        if (time[now-1] >= 0 && visited[now-1] == 0) {
            q.push(now-1);
           visited[now-1] = 1;
           time[now-1] = time[now] + 1;
        }
        if (time[now+1] <= 10000 && visited[now+1] == 0) {
            q.push(now+1);
            visited[now+1] = 1;
            time[now+1] = time[now] + 1;
        }
        if (time[now*2] <= 10000 && visited[now*2] == 0) {
            q.push(now*2);
            visited[now*2] = 1;
            time[now*2] = time[now] + 1;
        }
    }
    int path[10000], index = 0;
    int now = m;
    path[index] = now;
    index++;
    while(now != n) {
        //printf("===%d \n", now);
        if (now-1 >= 0 && visited[now-1] == 1 && time[now-1] == time[now]-1) {
            now = now - 1;
        }
        else if (now+1 <= 10000 && visited[now+1] == 1 && time[now+1] == time[now]-1) {
            now = now+1;
        }
        else if (now % 2 == 0 && visited[now/2] == 1 && time[now/2] == time[now]-1) {
            now = now/2;
        }
        path[index] = now;
        index++;
    }
    //return 0;

    for (int i=index-1; i>=0; i--) {
        printf("%d ", path[i]);
    }

    return 0;
}

'정보올림피아드-KOI > BOJ' 카테고리의 다른 글

백준 숫자카드 - 이분탐색  (0) 2022.03.18
백준 1,2,3 더하기 (브루트 포스)  (0) 2022.03.18
백준 일곱 난쟁이  (0) 2022.03.14
백준 2×n 타일링 2  (0) 2022.03.14
백준 꿀따기 21758번 (11점 )  (0) 2022.03.11

 

 

JW

 

 

#include <bits/stdc++.h>
using namespace std;
//토마토

int main() {
	queue<pair<int, int>> q;
	int n, m;
	int arr[1002][1002] = {0,}, visited[1002][1002] = {0,};
	cin >> n >> m;
	for (int i=1; i<=m; i++) {
		for (int j=1; j<=n; j++) {
			cin >> arr[i][j];
		}
	}

	for (int i=1; i<=m; i++) {
		for (int j=1; j<=n; j++) {
			if (arr[i][j] == 1) {
				q.push({i, j});
				visited[i][j] = 1;
			}
			else if (arr[i][j] == -1) {
				visited[i][j] = 1;
			}
		}
	}
	while (!q.empty()) {
		int x = q.front().first;
		int y = q.front().second;
		q.pop();
		if (x-1 != 0 && arr[x-1][y] == 0 && visited[x-1][y] == 0) {
			q.push({x-1, y});
			arr[x-1][y] = arr[x][y] + 1;
			visited[x-1][y] = 1;
		}
		if (x+1 != m+1 && arr[x+1][y] == 0 && visited[x+1][y] == 0) {
			q.push({x+1, y});
			arr[x+1][y] = arr[x][y] + 1;
			visited[x+1][y] = 1;
		}
		if (y-1 != 0 && arr[x][y-1] == 0 && visited[x][y-1] == 0) {
			q.push({x, y-1});
			arr[x][y-1] = arr[x][y] + 1;
			visited[x][y-1] = 1;
		}
		if (y+1 != n+1 && arr[x][y+1] == 0 && visited[x][y+1] == 0) {
			q.push({x, y+1});
			arr[x][y+1] = arr[x][y] + 1;
			visited[x][y+1] = 1;
		}
	}
	for (int i=1; i<=m; i++) {
		for (int j=1; j<=n; j++) {
			if (visited[i][j] == 0) {
				printf("-1");
				return 0;
			}
		}
	}
	int maxi = 0;
	for (int i=1; i<=m; i++) {
		for (int j=1; j<=n; j++) {
			if (arr[i][j] > maxi) {
				maxi = arr[i][j];
			}
		}
	}
	printf("%d", maxi-1);
}

 

 

'정보올림피아드-KOI > BOJ' 카테고리의 다른 글

백준 균형잡힌 세상  (0) 2022.03.07
백준 소수 구하기 1929  (0) 2022.03.07
스택 Stack  (0) 2022.02.04
단어 뒤집기 2  (0) 2021.12.31
백준 : 가운데를 말해요 1655번  (0) 2020.05.10

www.youtube.com/watch?v=7C9RgOcvkvo&list=PLRx0vPvlEmdAghTr5mXQxGpHjWqSz0dgC&index=3

 

 

 

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

 

1697번: 숨바꼭질

문제 수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 때 걷는다면 1초 후에 X-1 또는 X+1로 이동하게 된다. 순간이동을 하는 경우에는 1초 후에 2*X의 위치로 이동하게 된다. 수빈이와 동생의 위치가 주어졌을 때, 수빈이가 동생을 찾을 수 있는 가장 빠른 시간이 몇 초 후인지

www.acmicpc.net

BFS를 사용해서 쉽게풀수 있는 문제다.

BFS는 아래그림과 같이 그래프 순회방법중의 하나이다.

특히, BFS는 간선의 가중치가 모두 동일한 경우, 최단거리와 같은 최소비용 문제를 해결하기에 적합합니다.

 

아래 그래는 Graph의 표현 방법과 순회에 대해서 대략적으로 요약한 것이니 참고하시기 바랍니다.

인접리스트의 경우 실제 리스트를 사용하기 보다는 보통 vector를 사용해서 해결하는 경우 많으니 참고하세요.

 

 

아래 BFS의 슈도코드라고 할까요? 대략적인 알고리즘을 확인 하실수 있겠습니다.

 

자~!! 이제 본 숨바꼭질 문제의 풀이 방법입니다. 아래 그림을 통해 찬찬히 고민해보시기 바랍니다.

수빈이의 위치 X에서 1초후에 이동할 수 있는 곳은 X-1, X+1, X*2 입니다. 어떤 이동방법을 선택하더라도 1초가 걸리니까, 이것은 모든 간선의 가중치가 1초라고 보면 되겠네요.^^

 

그리고X-1을 할때는 X-1이 0보다 작으면 중단하면 되겠죠.

X+1, X*2의 경우는 다음 위치가 200,000보다 작거나 같은때만 처리해주면 되겠네요.^^

 

 

많은 도움되셨길바라며, 아래 소스코드 참고하세요.^^

 

#include <bits/stdc++.h>
using namespace std;

int main()
{
    int n,k,c[200005]={0,},v[200005]={0,},t;
    queue <int> q;
    scanf("%d %d",&n,&k);
    v[n]=1;
    c[n]=0;
    q.push(n);
    while(!q.empty())
    {
        t=q.front();
        q.pop();
        if(t-1 >= 0 && v[t-1]==0){
            q.push(t-1);
            c[t-1]=c[t]+1;
            v[t-1] = 1;
        }
        if(t+1 < 200000 && v[t+1]==0){
            q.push(t+1);
            c[t+1]=c[t]+1;
            v[t+1] = 1;
        }
         if(t*2 < 200000 && v[t*2]==0){
            q.push(t*2);
            c[t*2]=c[t]+1;
             v[t*2]=1;
        }
        //v[t-1]=v[t+1]=v[t*2]=1;
    }
    printf("%d",c[k]);
    return 0;
}

 

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

 

1260번: DFS와 BFS

첫째 줄에 정점의 개수 N(1 ≤ N ≤ 1,000), 간선의 개수 M(1 ≤ M ≤ 10,000), 탐색을 시작할 정점의 번호 V가 주어진다. 다음 M개의 줄에는 간선이 연결하는 두 정점의 번호가 주어진다. 어떤 두 정점 사이에 여러 개의 간선이 있을 수 있다. 입력으로 주어지는 간선은 양방향이다.

www.acmicpc.net

1. 단계 : 시작 정점을 방문했다고 표시하고, Queue에 push

void bfs(int start){
    checked[start]=1;
    queue<int> q;
    q.push(start);
    while(!q.emplace()){
        
    }
}

2. 단계 
시작 정점을 방문했다고 표시하고, Queue에 push
Queue가 빌때까지 반복하면서, queue의 front값을 받고, pop함

void bfs(int start){
    checked[start]=1;
    queue<int> q;
    q.push(start);
    while(!q.empty()){
        int current = q.front();
        q.pop();
        printf("%d ", current);
    }
}

3. 단계
시작 정점을 방문했다고 표시하고, Queue에 push
Queue가 빌때까지 반복하면서, queue의 front값을 받고, pop함

queue의 front 정점(current)을 대상으로 연결된 정점(next)들을 찾음
next중에 방문하지 않은 정점이면, 방문 표시하고 queue에 push
이것을 queue가 빌때까지 반복

void bfs(int start){
    checked[start]=1;
    queue<int> q;
    q.push(start);
    while(!q.empty()){
        int current = q.front();
        q.pop();
        printf("%d ", current);
        for(int i=0; i<vxy[current].size(); i++){
            int next=vxy[current][i];
            if(checked[next] == 0){
                q.push(next);
                checked[next]=1;
            }
        }
    }
}

 

 

전체 소스코드

#include <bits/stdc++.h>
using namespace std;
int checked[10000];
vector<int>vxy[10000];

void dfs(int start)
{
    checked[start]=1;
    printf("%d ",start);
    for(int i=0; i<vxy[start].size(); i++){
        int next=vxy[start][i];
        if(checked[next] == 0){
            dfs(next);
        }
    }
}

void bfs(int start){
    checked[start]=1;
    queue<int> q;
    q.push(start);
    while(!q.empty()){
        int current = q.front();
        q.pop();
        printf("%d ", current);
        for(int i=0; i<vxy[current].size(); i++){
            int next=vxy[current][i];
            if(checked[next] == 0){
                q.push(next);
                checked[next]=1;
            }
        }
    }
}

int main() {
    int a,b,c,n,m,i;
    scanf("%d %d %d",&n,&m,&c);
    for(i=1; i<=m; i++){
        scanf("%d %d",&a,&b);
        vxy[a].push_back(b);
        vxy[b].push_back(a);
    }

    for(i=1; i<=n; i++){
        sort(vxy[i].begin(),vxy[i].end());
    }

    dfs(c);
    for(i=0; i<=n; i++)checked[i]=0;
    printf("\n");
    bfs(c);

    return 0;
}

'정보올림피아드-KOI > BOJ' 카테고리의 다른 글

백준-N-Queen : 3344번  (0) 2019.12.26
백준 - 타일링 : 1793번  (0) 2019.12.23
백준 - N과 M (4) :15652 번  (0) 2019.12.19
백준 - N과 M (3) : 15651번  (0) 2019.12.19
백준 - A/B : 1008번  (0) 2019.12.19

+ Recent posts