Skip to content
Home » 아 맞다 우산 | [천관사복] 진옥으로 비교당하는 아이 7550 좋은 평가 이 답변

아 맞다 우산 | [천관사복] 진옥으로 비교당하는 아이 7550 좋은 평가 이 답변

당신은 주제를 찾고 있습니까 “아 맞다 우산 – [천관사복] 진옥으로 비교당하는 아이“? 다음 카테고리의 웹사이트 https://kk.taphoamini.com 에서 귀하의 모든 질문에 답변해 드립니다: https://kk.taphoamini.com/wiki/. 바로 아래에서 답을 찾을 수 있습니다. 작성자 아 맞다 우산 이(가) 작성한 기사에는 조회수 11,602회 및 좋아요 990개 개의 좋아요가 있습니다.

아 맞다 우산 주제에 대한 동영상 보기

여기에서 이 주제에 대한 비디오를 시청하십시오. 주의 깊게 살펴보고 읽고 있는 내용에 대한 피드백을 제공하세요!

d여기에서 [천관사복] 진옥으로 비교당하는 아이 – 아 맞다 우산 주제에 대한 세부정보를 참조하세요

■원곡 – https://youtu.be/olWvy0PiLfA
■짤막한 영상제작후기 – https://blog.naver.com/sookk6577/222572372804
===================================
\”인간들은 엉터리 날조를 사랑해 마지않는다.\” -천관사복 90장
…엉터리 날조 죄송합니다

아 맞다 우산 주제에 대한 자세한 내용은 여기를 참조하세요.

17244번: 아맞다우산

아 맞다 우산!!!” 경재 씨는 매번 외출하고 나서야 어떤 물건을 집에 놓고 왔다는 것을 떠올릴 때마다 자책감에 시달리는 것이 너무 싫었다. 외출이 잦은 경재 씨는 …

+ 여기에 표시

Source: www.acmicpc.net

Date Published: 12/8/2022

View: 8667

[ 백준 17244 ] 아 맞다 우산 (C++) – 얍문’s Coding World..

[ 백준 17244 ] 아 맞다 우산 (C++) · 1) 시작점에서 주어진 물건을 모두 줍고 도착점까지 갈 때 걸리는 최소 시간을 찾아야 하는 문제이다. · 본인은 이 …

+ 여기에 더 보기

Source: yabmoons.tistory.com

Date Published: 12/10/2022

View: 8512

아 맞다 우산 by 옥짱곡가 – SoundCloud

Stream 옥짱 – 아 맞다 우산 by 옥짱곡가 on desktop and mobile. Play over 265 million tracks for free on SoundCloud.

+ 여기에 표시

Source: soundcloud.com

Date Published: 11/11/2022

View: 2148

백준 17244번 아맞다우산 – 꾸준함

문제 링크입니다: https://www.acmicpc.net/problem/17244 17244번: 아맞다우산 경재씨는 저녁 약속을 가기 전 챙기지 않은 물건들이 있는 지 확인 …

+ 더 읽기

Source: jaimemin.tistory.com

Date Published: 9/5/2021

View: 9180

[백준] 17244번 : 아맞다우산 – 개발하는 고라니

[BFS + 비트마스크]. N x M 격자 맵에서 ‘X’로 표시된 모든 물건을 챙기고 탈출구 ‘E’로 최소한의 움직임으로 나가는 방법을 찾는 문제.

+ 여기에 표시

Source: dev-gorany.tistory.com

Date Published: 9/13/2022

View: 604

Top 25 아 맞다 우산 The 230 Detailed Answer

[ 백준 17244 ] 아 맞다 우산 (C++) · 1) 시작점에서 주어진 물건을 모두 줍고 도착점까지 갈 때 걸리는 최소 시간을 찾아야 하는 문제이다. · 본인은 이 …

+ 자세한 내용은 여기를 클릭하십시오

Source: toplist.khunganhtreotuong.vn

Date Published: 12/27/2022

View: 3948

[백준][C++] 17244 아맞다우산 – 거창한 시작

알고리즘 종류. – 구현. – BFS. 사고 과정. – 이 문제에서 중요한 조건은 재방문 처리이다. 특히 아래와 같은 상황이다. 시작점 S에서 빨간색 선으로 …

+ 여기에 자세히 보기

Source: conkjh032.tistory.com

Date Published: 10/22/2021

View: 5252

[백준/17244/파이썬] 아 맞다 ! 우산 – Mapin

아 맞다 우산!!!” 외출이 잦은 경재 씨는 반복되는 일을 근절하기 위해 꼭 챙겨야 할 물건들을 정리해보았다. 하지만 지갑, 스마트폰, 우산, 차 키, …

+ 여기에 더 보기

Source: dailymapins.tistory.com

Date Published: 10/22/2021

View: 212

주제와 관련된 이미지 아 맞다 우산

주제와 관련된 더 많은 사진을 참조하십시오 [천관사복] 진옥으로 비교당하는 아이. 댓글에서 더 많은 관련 이미지를 보거나 필요한 경우 더 많은 관련 기사를 볼 수 있습니다.

[천관사복] 진옥으로 비교당하는 아이
[천관사복] 진옥으로 비교당하는 아이

주제에 대한 기사 평가 아 맞다 우산

  • Author: 아 맞다 우산
  • Views: 조회수 11,602회
  • Likes: 좋아요 990개
  • Date Published: 2021. 11. 18.
  • Video Url link: https://www.youtube.com/watch?v=qx6OegXS1Y0

17244번: 아맞다우산

문제

경재씨는 저녁 약속을 가기 전 챙기지 않은 물건들이 있는 지 확인하고 있다. 필요한 물건은 전부 챙긴 것 같았고 외출 후 돌아오는 길에 경재씨는 외쳤다.

“아 맞다 우산!!!”

경재 씨는 매번 외출하고 나서야 어떤 물건을 집에 놓고 왔다는 것을 떠올릴 때마다 자책감에 시달리는 것이 너무 싫었다.

외출이 잦은 경재 씨는 반복되는 일을 근절하기 위해 꼭 챙겨야 할 물건들을 정리해보았다. 하지만 지갑, 스마트폰, 우산, 차 키, 이어폰, 시계, 보조 배터리 등 종류와 개수가 너무 많았다.

평소 불필요한 움직임을 아주 싫어하는 경재 씨는 이 물건들을 최대한 빠르게 챙겨서 외출하는 이동 경로를 알고 싶었다.

경재 씨는 한 걸음에 상하좌우에 인접한 칸으로만 움직일 수 있다.

경재 씨를 위해 집을 위에서 바라본 모습과 챙겨야 할 물건들의 위치들을 알고 있을 때, 물건을 모두 챙겨서 외출하기까지 최소 몇 걸음이 필요한지 구하는 프로그램을 작성하자.

[ 백준 17244 ] 아 맞다 우산 (C++)

백준의 아 맞다 우산(17244) 문제이다.

[ 문제 바로가기 ] [ 문제풀이 ]

1) 시작점에서 주어진 물건을 모두 줍고 도착점까지 갈 때 걸리는 최소 시간을 찾아야 하는 문제이다.

본인은 이 문제를 너비우선탐색(BFS)을 이용해서 풀어보았는데, 방문체크를 단순히 ‘몇 개 주웠는지’ 로는

풀 수가 없다. 왜냐하면 다음과 같은 경우를 생각해보자.

위와 같은 맵이 존재할 때, 우리가 주워야할 물건은 4개가 있다. 그런데 단순히 몇 개 주었는지만으로 체크를 한다면

다음과 같은 경우가 발생할 것이다.

시작점 → 빨강색X로 향할 때 체크 : 0개를 주웠을 때 빨강색 X에 방문한 적이 있는지 ? → 없으므로 1개를 주웠다고

표시하며 방문 → 파랑색 X로 향할 때 체크 : 1개를 주웠을 때 파랑색 X에 방문한 적이 있는지 ? → 없으므로 파랑색 물건을

줍고 2개를 주웠다고 표시하며 방문 → 빨강색X로 향할 때 체크 : 2개를 주웠을 때 빨강색 X에 방문한 적이 있는지 ?

→ 없으므로 3개를 주웠다고 표시하며 방문 → 파랑색 X로 향할 때 체크 : 4개를 주웠을 때 파랑색 X에 방문한 적이

있는지 ? → 없으므로 파랑색 물건을 줍고 4개를 주웠다고 표시하며 방문 → E로 향함.

이렇게 되면 실제로 물건을 4개다 줍지 않았음에도, 4개를 주웠다고 잘못 판단하고 결론에 도달하는 경우가 존재한다.

따라서 단순히 ‘몇 개를 주었는지’ 로는 문제를 해결할 수가 없다.

접근할 때, ‘몇 개’가 아닌 ‘빨강색 X를 주웠는지’ 혹은 ‘파랑색 X를 주웠는지’ 이런 식의 개념으로 접근을 해야 한다.

그래서 이 부분을 위해서 본인은 비트마스크를 사용했다.

본인은 물건들을 X로 놓지 않고, 각 물건들이 입력됨과 동시에 번호로 표시해 주었다.

예를 들면 위의 경우, 빨강색 X = ‘0’ , 파랑색 X = ‘1’, 나머지 X들 = ‘2’, ‘3’ 이런식으로 char형 문자로 저장해 주었다.

그리고 위의 물건들을 비트마스크로 표시하는 것이다. 주웠을 때는 1, 아직 줍지 않았을 때는 0

최종적으로 우리가 모든 물건을 다 주웠다면 모든 비트가 ‘1’로 표시되어 있을 것이다.

위의 그림같은 경우 주워야할 물건이 4개이므로 ‘1111’ 이 되어야 모두 주운 것이다.

여기서 잘 생각해야 할 것이, 실제로 우리는 2진수로 비트를 표현하는 것이 아니라 ,10진수를 2진수 처럼 표현할 것이다.

2) 본인은 방문체크를 위한 bool 형 Visit배열을 3차원으로 선언해 주었다.

크기는 Visit[50][50][35]로 선언해 주었다.

앞에 50 50은 맵의 최대 크기, 즉 x좌표와 y좌표를 나타내는 부분이고, 뒤에 35를 한번 봐보자.

물건은 최대 5개까지 있을 수 있다. 즉, 물건 5개를 모두 주웠다면 비트가 ‘11111’ 로 표현되야 할 것이다.

하지만, 우리는 실제로 2진수를 사용하는 것이 아닌 10진수를 2진수처럼 표현하는 것이다. 즉, ‘11111’을 십진수로

나타내면 31이다. 즉, 물건이 최대 5개가 있더라도 ‘11111’보다 더 큰 수는 나오지 않기 때문에, 다시 말해서 ’31’보다

더 큰 수는 나오지 않기 때문에 배열의 크기를 31보다 조금 더 큰 35로 설정해 주었다.

그럼 물건을 줍게되면 어떻게 체크를 해줘야 할까 ??

예를 들어서 물건이 4개가 있고, 현재 비트가 0000 이라고 가정해보자. 즉, 아직 물건을 하나도 줍지 못한 상태이다.

여기서 ‘0’번 물건을 주웠다고 가정해보면, 아마 비트는 0001이 될 것이다.

0000 과 어떤 값을 무슨 연산을 해줘야 0001이 나올까 ?? 바로 0001과 or 연산을 하면 된다.

0000 | 0001 = 0001 이기 때문이다.

그럼 ‘1’번물건을 주웠다고 가정해보자. 아마 비트는 0010이 되어야 할 것이다.

이 값은, 0000 | 0010 을 해주면 나오게 되는 값이다.

즉 ! “1을 물건의 번호만큼 << shift 연산 후, or연산을 진행" 하면 되는 것이다. '0'번 물건을 주운 경우를 보자. 현재 비트 = 0000 이고, 위에서 말한대로 1을 물건의 번호만큼 << shift연산 후 or 연산을 해보자. 1을 물건의 번호인 '0'만큼 shift연산을 하게되면, 0001이 될 것이다. 1은 2진수로 0001이기 때문에 ! 그 후, 0000과 0001을 or 연산을 하면 '0'번 물건을 주웠습니다 라고 표시할 수 있는 비트가 생성되는 것이다. '1'번 물건을 줍게 되면, 1을 '1'번만큼 << shift연산을 하게되면 0001 → 0010 이 되고, 이 후 or 연산을 하게 되면 0010 이 되는 것이다. 이런식으로 x번 물건을 주웠는지 안주웠는지를 체크를 해주면서 탐색을 진행하면 된다. 3) 위에서는 비트마스크를 이용한 풀이를 알아보았다. 본인은 또 한가지 방법으로 풀이를 해보았는데, 이 방법은 모든 물건에 순서를 만들어 주는 것이다. 물건을 주울 순서를 정한 후, 해당 물건을 순서대로 주워보고 걸리는 시간 중 최소값을 찾는 방식이다. 따라서 이 풀이에는 '순열'을 구현하는 과정이 들어간다. 순열을 구현하는 방법을 모른다면 아래의 글을 읽고 오자 ! [ 순열 구현하기 (Click) ] 각 물건들의 순서를 정해주고, BFS 탐색으로 시작점 → 순서가 정해진 물건들을 순서대로 줍기 → 도착점 으로 가는 시간들 중, 최소 시간을 정답으로 채택하는 방식이다. 주의해야 할 부분은 주워야 할 물건의 갯수가 0개일 때가 존재한다. 따라서, 0 개일 때는, 시작점에서 도착점으로 바로 탐색을 해줘야 하는 것이다. [ 비트마스크 풀이 소스코드 ] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 #include < iostream > #include < queue > #define endl ”

” #define MAX 50 using namespace std ; int N, M, Bit; char MAP[MAX][MAX]; bool Visit[MAX][MAX][ 35 ]; int dx[] = { 0 , 0 , 1 , – 1 }; int dy[] = { 1 , – 1 , 0 , 0 }; pair < int , int > Start, End; void Input() { int Idx = 0 ; cin > > M > > N; for ( int i = 0 ; i < N; i + + ) { for ( int j = 0 ; j < M; j + + ) { cin > > MAP[i][j]; if (MAP[i][j] = = ‘S’ ) { Start.first = i; Start.second = j; } else if (MAP[i][j] = = ‘X’ ) { MAP[i][j] = (Idx + + ) + ‘0’ ; } } } Bit = ( 1 < < Idx) - 1 ; } void Solution() { queue < pair < pair < int , int > , pair < int , int > > > Q; Q.push( make_pair ( make_pair (Start.first, Start.second), make_pair ( 0 , 0 ))); Visit[Start.first][Start.second][ 0 ] = true ; while (Q.empty() = = 0 ) { int x = Q. front ().first.first; int y = Q. front ().first.second; int Cnt = Q. front ().second.first; int Bit_State = Q. front ().second.second; Q. pop (); if (MAP[x][y] = = ‘E’ & & Bit_State = = Bit) { cout < < Cnt < < endl ; return ; } for ( int i = 0 ; i < 4 ; i + + ) { int nx = x + dx[i]; int ny = y + dy[i]; int nB = Bit_State; if (nx > = 0 & & ny > = 0 & & nx < N & & ny < M) { if ( '0' < = MAP[nx][ny] & & MAP[nx][ny] < '5' ) { nB = Bit_State | ( 1 < < MAP[nx][ny] - '0' ); if (Visit[nx][ny][nB] = = false ) { Visit[nx][ny][nB] = true ; Q.push( make_pair ( make_pair (nx, ny), make_pair (Cnt + 1 , nB))); } } else if (MAP[nx][ny] ! = '#' ) { if (Visit[nx][ny][nB] = = false ) { Visit[nx][ny][nB] = true ; Q.push( make_pair ( make_pair (nx, ny), make_pair (Cnt + 1 , nB))); } } } } } } void Solve() { Input(); Solution(); } int main( void ) { ios::sync_with_stdio( false ); cin .tie( NULL ); cout .tie( NULL ); //freopen("Input.txt", "r", stdin); Solve(); return 0 ; } Colored by Color Scripter cs [ 순열을 통한 풀이 소스코드 ] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 #include < iostream > #include < queue > #include < vector > #include < cstring > #define endl ”

” #define MAX 50 using namespace std ; int N, M, Answer = 987654321 ; char MAP[MAX][MAX]; bool Visit[MAX][MAX]; bool Select[ 5 ]; int dx[] = { 0 , 0 , 1 , – 1 }; int dy[] = { 1 , – 1 , 0 , 0 }; vector < pair < int , int > > V, Order; pair < int , int > Start, End; int Min( int A, int B) { if (A < B) return A; return B; } void Input() { cin > > M > > N; for ( int i = 0 ; i < N; i + + ) { for ( int j = 0 ; j < M; j + + ) { cin > > MAP[i][j]; if (MAP[i][j] = = ‘X’ ) { V. push_back ( make_pair (i, j)); MAP[i][j] = ‘.’ ; } else if (MAP[i][j] = = ‘S’ ) { Start.first = i; Start.second = j; MAP[i][j] = ‘.’ ; } else if (MAP[i][j] = = ‘E’ ) { End.first = i; End.second = j; MAP[i][j] = ‘.’ ; } } } } int BFS( int Sx, int Sy, int Ex, int Ey) { memset(Visit, false , sizeof (Visit)); queue < pair < pair < int , int > , int > > Q; Q.push( make_pair ( make_pair (Sx, Sy), 0 )); Visit[Sx][Sy] = true ; while (Q.empty() = = 0 ) { int x = Q. front ().first.first; int y = Q. front ().first.second; int Cnt = Q. front ().second; Q. pop (); if (x = = Ex & & y = = Ey) return Cnt; for ( int i = 0 ; i < 4 ; i + + ) { int nx = x + dx[i]; int ny = y + dy[i]; if (nx > = 0 & & ny > = 0 & & nx < N & & ny < M) { if (MAP[nx][ny] = = '.' & & Visit[nx][ny] = = false ) { Visit[nx][ny] = true ; Q.push( make_pair ( make_pair (nx, ny), Cnt + 1 )); } } } } } void Calculate() { int S = Order. size (); int Dist = BFS(Start.first, Start.second, Order[ 0 ].first, Order[ 0 ].second); for ( int i = 0 ; i < S - 1 ; i + + ) { Dist = Dist + BFS(Order[i].first, Order[i].second, Order[i + 1 ].first, Order[i + 1 ].second); } Dist = Dist + BFS(Order[S - 1 ].first, Order[S - 1 ].second, End.first, End.second); Answer = Min(Answer, Dist); } void DFS( int Cnt) { if (Cnt = = V. size ()) { Calculate(); return ; } for ( int i = 0 ; i < V. size (); i + + ) { if (Select[i] = = true ) continue ; Select[i] = true ; Order. push_back (V[i]); DFS(Cnt + 1 ); Order.pop_back(); Select[i] = false ; } } void Solution() { if (V. size () = = 0 ) { Answer = BFS(Start.first, Start.second, End.first, End.second); cout < < Answer < < endl ; return ; } DFS( 0 ); cout < < Answer < < endl ; } void Solve() { Input(); Solution(); } int main( void ) { ios::sync_with_stdio( false ); cin .tie( NULL ); cout .tie( NULL ); //freopen("Input.txt", "r", stdin); Solve(); return 0 ; } Colored by Color Scripter cs

백준 17244번 아맞다우산

문제 링크입니다: https://www.acmicpc.net/problem/17244

비트마스킹을 통해 아이템을 주웠는지 판별해야하는 흥미로운 BFS 문제였습니다.

물건 ‘X’ 마다 각각 고유 인덱스를 부여하여 비트 연산을 통해 주웠는지를 판별하는 것이 핵심이였습니다.

물건은 최대 5개이기 때문에 인덱스는 최대 4이고 0 ~ 4 까지 모두 표시하기 위해서는 크기가 2^5 즉, 32인 배열이 필요합니다.

물건을 줍는 과정에서 같은 칸을 밟을 수 있기 때문에 평소처럼 이차원 visited 배열을 사용하면 안되고 어떤 물건을 주웠는가까지 표시하는 삼차원 visited 배열을 사용해야했습니다.

따라서, visited 배열을 visited[MAX][MAX][1 << MAX_STUFF] 로 표시했습니다. BFS 탐색을 진행할 때는 다음 칸에 줍지 않은 물건 여부를 확인한 뒤 1. 줍지 않은 물건이 있다면 checked 변수에 비트 연산을 통해 주웠다고 표시하고 큐에 넣습니다. 2. 줍지 않은 물건이 없고 갈 수 있는 칸이라면 그대로 큐에 넣습니다. 3. 모든 물건을 주웠고 도착점에 도착한다면 time을 출력하고 프로그램을 종료합니다. 문제 조건에 모든 물건을 챙길 수 없는 경우는 주어지지 않는다. 라고 나와있기 때문에 해당 부분에 대해서는 예외처리를 하지 않았습니다. 개발환경:Visual Studio 2017 지적, 조언, 질문 환영입니다! 댓글 남겨주세요~ 반응형

[백준] 17244번 : 아맞다우산

반응형

[BFS + 비트마스크]

N x M 격자 맵에서 ‘X’로 표시된 모든 물건을 챙기고 탈출구 ‘E’로 최소한의 움직임으로 나가는 방법을 찾는 문제. 격자의 크기 제한이 최대 50×50이고 물건의 개수가 최대 5개라서 비트마스킹을 안써도 메모리적인 부분에서 큰 손실은 없을 것 같으나, 물건이 모두 ‘X’로 동일하여 현재 내가 특정 정점에 방문했을 때, 어떤 물건을 갖고 있는 지를 체크하는 것이 비트마스킹만큼 좋은 것이 없기에 비트마스킹을 사용했다.

먼저 입력을 받을 때 ‘X’인 곳을 ‘0’, ‘1’, ‘2’, …처럼 X가 아닌 숫자로 지정해놓는다. 이는 물건에 “인덱스”를 부여하는 효과를 가져오며 물건이 몇 개 존재하는지 또한 알아낼 수 있다.

int sY = 0, sX = 0; char idx = ‘0’; for(int i=1; i<=n; i++) { char[] str = br.readLine().toCharArray(); for (int j = 1; j <= m; j++) { map[i][j] = str[j - 1]; if (map[i][j] == 'X') { map[i][j] = idx++; k++; } else if (map[i][j] == 'S') { sY = i; sX = j; } } } 그럼 이제 지도에는 S, ., #, E, 0 ~ 4가 존재할 것이고, BFS를 시작점 S에서 부터 탐색을 한다. 1) '0', '1', '2', '3', '4' 일 때 현재 방문한 정점이 위의 값 중 하나라면, 물건이 있는 곳이다. 이때 내가 이미 해당 물건을 챙겼는지 여부를 비트마스킹으로 체크한다. 만약 이미 챙겼던 물건이라면 item은 변화를 주지 않고 그저 방문한다. 아직 챙기지 않은 물건이라면 챙기고 방문한다. if(map[ny][nx] >= ‘0’ && map[ny][nx] <= '5'){ int num = map[ny][nx] - '0'; if( (item & (1 << num)) == 0){ nItem = item | (1 << num); visit[ny][nx][nItem] = true; Q.add(new Point(ny, nx, move + 1, nItem)); continue; } } 2) '#'와 숫자를 제외한 나머지 이때는 그냥 방문하기만 하면 된다. # 종료 시퀀스 - 물건을 모두 챙겼는지? 현재 정점이 'E' 인지 # Code

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.LinkedList; import java.util.Queue; import java.util.StringTokenizer; public class Main { static class Point{ int y, x, move, item; public Point(int yy, int xx, int m, int it){ y=yy; x=xx; move=m; item=it; } } //n : 높이, m : 너비, k : 물건의 개수 static int n, m, k; static int[] Y = {-1,1,0,0}, X={0,0,-1,1}; static char[][] map = new char[51][51]; static boolean[][][] visit = new boolean[51][51][(1 << 6)]; static int BFS(int sy, int sx) { Queue Q = new LinkedList<>(); visit[sy][sx][0] = true; Q.add(new Point(sy, sx, 0, 0)); while(!Q.isEmpty()){ Point p = Q.poll(); int y = p.y; int x = p.x; int move = p.move; int item = p.item; if(map[y][x] == ‘E’ && item == ((1 << k) - 1)) return move; for(int a=0; a<4; a++){ int ny = y+Y[a]; int nx = x+X[a]; int nItem = 0; if(ny < 1 || nx < 1 || ny > n || nx > m || visit[ny][nx][item] || map[ny][nx] == ‘#’) continue; if(map[ny][nx] >= ‘0’ && map[ny][nx] <= '5'){ int num = map[ny][nx] - '0'; if( (item & (1 << num)) == 0){ nItem = item | (1 << num); visit[ny][nx][nItem] = true; Q.add(new Point(ny, nx, move + 1, nItem)); continue; } } visit[ny][nx][item] = true; Q.add(new Point(ny, nx, move + 1, item)); } } return 0; } public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); m = Integer.parseInt(st.nextToken()); n = Integer.parseInt(st.nextToken()); int sY = 0, sX = 0; char idx = '0'; for(int i=1; i<=n; i++) { char[] str = br.readLine().toCharArray(); for (int j = 1; j <= m; j++) { map[i][j] = str[j - 1]; if (map[i][j] == 'X') { map[i][j] = idx++; k++; } else if (map[i][j] == 'S') { sY = i; sX = j; } } } System.out.println(BFS(sY, sX)); } } 반응형

Top 25 아 맞다 우산 The 230 Detailed Answer

[천관사복] 진옥으로 비교당하는 아이

[천관사복] 진옥으로 비교당하는 아이

17244번: 아맞다우산

Article author: www.acmicpc.net

Reviews from users: 27546 Ratings

Ratings Top rated: 3.8

Lowest rated: 1

Summary of article content: Articles about 17244번: 아맞다우산 아 맞다 우산!!!” 경재 씨는 매번 외출하고 나서야 어떤 물건을 집에 놓고 왔다는 것을 떠올릴 때마다 자책감에 시달리는 것이 너무 싫었다. 외출이 잦은 경재 씨는 … …

Most searched keywords: Whether you are looking for 17244번: 아맞다우산 아 맞다 우산!!!” 경재 씨는 매번 외출하고 나서야 어떤 물건을 집에 놓고 왔다는 것을 떠올릴 때마다 자책감에 시달리는 것이 너무 싫었다. 외출이 잦은 경재 씨는 … ACM-ICPC, ICPC, 프로그래밍, 온라인 저지, 정보올림피아드, 코딩, 알고리즘, 대회, 올림피아드, 자료구조

Table of Contents:

문제

입력

출력

제한

예제 입력 1

복사

예제 출력 1

복사

힌트

출처

Baekjoon Online Judge

채점 현황

문제

유저 대회 고등학교 대회

출처

대학교 대회

도움말

17244번: 아맞다우산

Read More

[ 백준 17244 ] 아 맞다 우산 (C++) :: 얍문’s Coding World..

Article author: yabmoons.tistory.com

Reviews from users: 22577 Ratings

Ratings Top rated: 4.9

Lowest rated: 1

Summary of article content: Articles about [ 백준 17244 ] 아 맞다 우산 (C++) :: 얍문’s Coding World.. [ 백준 17244 ] 아 맞다 우산 (C++) · 1) 시작점에서 주어진 물건을 모두 줍고 도착점까지 갈 때 걸리는 최소 시간을 찾아야 하는 문제이다. · 본인은 이 … …

Most searched keywords: Whether you are looking for [ 백준 17244 ] 아 맞다 우산 (C++) :: 얍문’s Coding World.. [ 백준 17244 ] 아 맞다 우산 (C++) · 1) 시작점에서 주어진 물건을 모두 줍고 도착점까지 갈 때 걸리는 최소 시간을 찾아야 하는 문제이다. · 본인은 이 … 백준의 아 맞다 우산(17244) 문제이다. [ 문제 바로가기 ] [ 문제풀이 ] 1) 시작점에서 주어진 물건을 모두 줍고 도착점까지 갈 때 걸리는 최소 시간을 찾아야 하는 문제이다. 본인은 이 문제를 너비우선탐색(B..Programming

Table of Contents:

[ 백준 17244 ] 아 맞다 우산 (C++)

티스토리툴바

[ 백준 17244 ] 아 맞다 우산 (C++) :: 얍문’s Coding World..

Read More

아 맞다 우산 – YouTube

Article author: www.youtube.com

Reviews from users: 18808 Ratings

Ratings Top rated: 3.9

Lowest rated: 1

Summary of article content: Articles about 아 맞다 우산 – YouTube 아 맞다 우산. 아 맞다 우산. 1.01K subscribers. Subscribe. 우산 블로그☂ / Blog. Home. Veos. Playlists. Community. Channels. …

Most searched keywords: Whether you are looking for 아 맞다 우산 – YouTube 아 맞다 우산. 아 맞다 우산. 1.01K subscribers. Subscribe. 우산 블로그☂ / Blog. Home. Veos. Playlists. Community. Channels. 유튜브 까짓거 한번 해보죠video, chia sẻ, điện thoại có máy ảnh, điện thoại quay video, miễn phí, tải lên

Table of Contents:

아 맞다 우산 – YouTube

Read More

백준 17244번 아맞다우산

Article author: jaimemin.tistory.com

Reviews from users: 22641 Ratings

Ratings Top rated: 4.5

Lowest rated: 1

Summary of article content: Articles about 백준 17244번 아맞다우산 문제 링크입니다: https://www.acmicpc.net/problem/17244 17244번: 아맞다우산 경재씨는 저녁 약속을 가기 전 챙기지 않은 물건들이 있는 지 확인 … …

Most searched keywords: Whether you are looking for 백준 17244번 아맞다우산 문제 링크입니다: https://www.acmicpc.net/problem/17244 17244번: 아맞다우산 경재씨는 저녁 약속을 가기 전 챙기지 않은 물건들이 있는 지 확인 … 문제 링크입니다: https://www.acmicpc.net/problem/17244 17244번: 아맞다우산 경재씨는 저녁 약속을 가기 전 챙기지 않은 물건들이 있는 지 확인하고 있다. 필요한 물건은 전부 챙긴 것 같았고 외출 후 돌아오는..소소한 프로그래밍과 약간의 게임

Table of Contents:

백준 17244번 아맞다우산

티스토리툴바

백준 17244번 아맞다우산

Read More

[백준][C++] 17244 아맞다우산

Article author: conkjh032.tistory.com

Reviews from users: 12106 Ratings

Ratings Top rated: 3.3

Lowest rated: 1

Summary of article content: Articles about [백준][C++] 17244 아맞다우산 알고리즘 종류. – 구현. – BFS. 사고 과정. – 이 문제에서 중요한 조건은 재방문 처리이다. 특히 아래와 같은 상황이다. 시작점 S에서 빨간색 선으로 … …

Most searched keywords: Whether you are looking for [백준][C++] 17244 아맞다우산 알고리즘 종류. – 구현. – BFS. 사고 과정. – 이 문제에서 중요한 조건은 재방문 처리이다. 특히 아래와 같은 상황이다. 시작점 S에서 빨간색 선으로 … www.acmicpc.net/problem/17244 17244번: 아맞다우산 경재씨는 저녁 약속을 가기 전 챙기지 않은 물건들이 있는 지 확인하고 있다. 필요한 물건은 전부 챙긴 것 같았고 외출 후 돌아오는 길에 경재씨는 외쳤다. “..쉽고 간단하고 재미있게

Table of Contents:

[백준][C++] 17244 아맞다우산

티스토리툴바

[백준][C++] 17244 아맞다우산

Read More

[백준/17244/파이썬] 아 맞다 ! 우산 — Mapin

Article author: dailymapins.tistory.com

Reviews from users: 316 Ratings

Ratings Top rated: 3.3

Lowest rated: 1

Summary of article content: Articles about [백준/17244/파이썬] 아 맞다 ! 우산 — Mapin 아 맞다 우산!!!” 외출이 잦은 경재 씨는 반복되는 일을 근절하기 위해 꼭 챙겨야 할 물건들을 정리해보았다. 하지만 지갑, 스마트폰, 우산, 차 키, … …

Most searched keywords: Whether you are looking for [백준/17244/파이썬] 아 맞다 ! 우산 — Mapin 아 맞다 우산!!!” 외출이 잦은 경재 씨는 반복되는 일을 근절하기 위해 꼭 챙겨야 할 물건들을 정리해보았다. 하지만 지갑, 스마트폰, 우산, 차 키, … https://www.acmicpc.net/problem/17244 17244번: 아맞다우산 경재씨는 저녁 약속을 가기 전 챙기지 않은 물건들이 있는 지 확인하고 있다. 필요한 물건은 전부 챙긴 것 같았고 외출 후 돌아오는 길에 경재씨는 외..

Table of Contents:

[백준/17244/파이썬] 아 맞다 ! 우산 — Mapin

Read More

[백준] 17244번 : 아맞다우산

Article author: dev-gorany.tistory.com

Reviews from users: 22421 Ratings

Ratings Top rated: 3.8

Lowest rated: 1

Summary of article content: Articles about [백준] 17244번 : 아맞다우산 [BFS + 비트마스크]. N x M 격자 맵에서 ‘X’로 표시된 모든 물건을 챙기고 탈출구 ‘E’로 최소한의 움직임으로 나가는 방법을 찾는 문제. …

Most searched keywords: Whether you are looking for [백준] 17244번 : 아맞다우산 [BFS + 비트마스크]. N x M 격자 맵에서 ‘X’로 표시된 모든 물건을 챙기고 탈출구 ‘E’로 최소한의 움직임으로 나가는 방법을 찾는 문제. 17244번: 아맞다우산 경재씨는 저녁 약속을 가기 전 챙기지 않은 물건들이 있는 지 확인하고 있다. 필요한 물건은 전부 챙긴 것 같았고 외출 후 돌아오는 길에 경재씨는 외쳤다. “아 맞다 우산!!!” 경재 씨는 매번..

Table of Contents:

개발하는 고라니

[백준] 17244번 아맞다우산 본문

티스토리툴바

[백준] 17244번 : 아맞다우산

Read More

boj 17244 아맞다우산 :: 취미가 알고리즘

Article author: emoney96.tistory.com

Reviews from users: 22413 Ratings

Ratings Top rated: 3.2

Lowest rated: 1

Summary of article content: Articles about boj 17244 아맞다우산 :: 취미가 알고리즘 boj 17244 아맞다우산 … 챙겨야 하는 물건은 최대 5개이므로 bfs + 비트마스킹이 가능합니다. visit[x][y][bit]: 좌표 (x, y)에 도착했을 때 찾은 물건의 … …

Most searched keywords: Whether you are looking for boj 17244 아맞다우산 :: 취미가 알고리즘 boj 17244 아맞다우산 … 챙겨야 하는 물건은 최대 5개이므로 bfs + 비트마스킹이 가능합니다. visit[x][y][bit]: 좌표 (x, y)에 도착했을 때 찾은 물건의 … https://www.acmicpc.net/problem/17244 17244번: 아맞다우산 경재씨는 저녁 약속을 가기 전 챙기지 않은 물건들이 있는 지 확인하고 있다. 필요한 물건은 전부 챙긴 것 같았고 외출 후 돌아오는 길에 경재씨는 외..

Table of Contents:

boj 17244 아맞다우산

티스토리툴바

boj 17244 아맞다우산 :: 취미가 알고리즘

Read More

[백준] 17244번 아맞다우산 :: 컴영의 기록지

Article author: comyoung.tistory.com

Reviews from users: 23716 Ratings

Ratings Top rated: 3.0

Lowest rated: 1

Summary of article content: Articles about [백준] 17244번 아맞다우산 :: 컴영의 기록지 17244 아맞다우산. 문제. 경재씨는 저녁 약속을 가기 전 챙기지 않은 물건들이 있는 지 확인하고 있다. 필요한 물건은 전부 챙긴 것 같았고 외출 후 … …

Most searched keywords: Whether you are looking for [백준] 17244번 아맞다우산 :: 컴영의 기록지 17244 아맞다우산. 문제. 경재씨는 저녁 약속을 가기 전 챙기지 않은 물건들이 있는 지 확인하고 있다. 필요한 물건은 전부 챙긴 것 같았고 외출 후 … 17244 아맞다우산 문제 경재씨는 저녁 약속을 가기 전 챙기지 않은 물건들이 있는 지 확인하고 있다. 필요한 물건은 전부 챙긴 것 같았고 외출 후 돌아오는 길에 경재씨는 외쳤다. “아 맞다 우산!!!” 경재 씨는 매..

Table of Contents:

TAG

관련글 관련글 더보기

인기포스트

[백준] 17244번 아맞다우산 :: 컴영의 기록지

Read More

See more articles in the same category here: toplist.khunganhtreotuong.vn/blog.

[ 백준 17244 ] 아 맞다 우산 (C++)

백준의 아 맞다 우산(17244) 문제이다. [ 문제 바로가기 ] [ 문제풀이 ] 1) 시작점에서 주어진 물건을 모두 줍고 도착점까지 갈 때 걸리는 최소 시간을 찾아야 하는 문제이다. 본인은 이 문제를 너비우선탐색(BFS)을 이용해서 풀어보았는데, 방문체크를 단순히 ‘몇 개 주웠는지’ 로는 풀 수가 없다. 왜냐하면 다음과 같은 경우를 생각해보자. 위와 같은 맵이 존재할 때, 우리가 주워야할 물건은 4개가 있다. 그런데 단순히 몇 개 주었는지만으로 체크를 한다면 다음과 같은 경우가 발생할 것이다. 시작점 → 빨강색X로 향할 때 체크 : 0개를 주웠을 때 빨강색 X에 방문한 적이 있는지 ? → 없으므로 1개를 주웠다고 표시하며 방문 → 파랑색 X로 향할 때 체크 : 1개를 주웠을 때 파랑색 X에 방문한 적이 있는지 ? → 없으므로 파랑색 물건을 줍고 2개를 주웠다고 표시하며 방문 → 빨강색X로 향할 때 체크 : 2개를 주웠을 때 빨강색 X에 방문한 적이 있는지 ? → 없으므로 3개를 주웠다고 표시하며 방문 → 파랑색 X로 향할 때 체크 : 4개를 주웠을 때 파랑색 X에 방문한 적이 있는지 ? → 없으므로 파랑색 물건을 줍고 4개를 주웠다고 표시하며 방문 → E로 향함. 이렇게 되면 실제로 물건을 4개다 줍지 않았음에도, 4개를 주웠다고 잘못 판단하고 결론에 도달하는 경우가 존재한다. 따라서 단순히 ‘몇 개를 주었는지’ 로는 문제를 해결할 수가 없다. 접근할 때, ‘몇 개’가 아닌 ‘빨강색 X를 주웠는지’ 혹은 ‘파랑색 X를 주웠는지’ 이런 식의 개념으로 접근을 해야 한다. 그래서 이 부분을 위해서 본인은 비트마스크를 사용했다. 본인은 물건들을 X로 놓지 않고, 각 물건들이 입력됨과 동시에 번호로 표시해 주었다. 예를 들면 위의 경우, 빨강색 X = ‘0’ , 파랑색 X = ‘1’, 나머지 X들 = ‘2’, ‘3’ 이런식으로 char형 문자로 저장해 주었다. 그리고 위의 물건들을 비트마스크로 표시하는 것이다. 주웠을 때는 1, 아직 줍지 않았을 때는 0 최종적으로 우리가 모든 물건을 다 주웠다면 모든 비트가 ‘1’로 표시되어 있을 것이다. 위의 그림같은 경우 주워야할 물건이 4개이므로 ‘1111’ 이 되어야 모두 주운 것이다. 여기서 잘 생각해야 할 것이, 실제로 우리는 2진수로 비트를 표현하는 것이 아니라 ,10진수를 2진수 처럼 표현할 것이다. 2) 본인은 방문체크를 위한 bool 형 Visit배열을 3차원으로 선언해 주었다. 크기는 Visit[50][50][35]로 선언해 주었다. 앞에 50 50은 맵의 최대 크기, 즉 x좌표와 y좌표를 나타내는 부분이고, 뒤에 35를 한번 봐보자. 물건은 최대 5개까지 있을 수 있다. 즉, 물건 5개를 모두 주웠다면 비트가 ‘11111’ 로 표현되야 할 것이다. 하지만, 우리는 실제로 2진수를 사용하는 것이 아닌 10진수를 2진수처럼 표현하는 것이다. 즉, ‘11111’을 십진수로 나타내면 31이다. 즉, 물건이 최대 5개가 있더라도 ‘11111’보다 더 큰 수는 나오지 않기 때문에, 다시 말해서 ’31’보다 더 큰 수는 나오지 않기 때문에 배열의 크기를 31보다 조금 더 큰 35로 설정해 주었다. 그럼 물건을 줍게되면 어떻게 체크를 해줘야 할까 ?? 예를 들어서 물건이 4개가 있고, 현재 비트가 0000 이라고 가정해보자. 즉, 아직 물건을 하나도 줍지 못한 상태이다. 여기서 ‘0’번 물건을 주웠다고 가정해보면, 아마 비트는 0001이 될 것이다. 0000 과 어떤 값을 무슨 연산을 해줘야 0001이 나올까 ?? 바로 0001과 or 연산을 하면 된다. 0000 | 0001 = 0001 이기 때문이다. 그럼 ‘1’번물건을 주웠다고 가정해보자. 아마 비트는 0010이 되어야 할 것이다. 이 값은, 0000 | 0010 을 해주면 나오게 되는 값이다. 즉 ! “1을 물건의 번호만큼 << shift 연산 후, or연산을 진행" 하면 되는 것이다. '0'번 물건을 주운 경우를 보자. 현재 비트 = 0000 이고, 위에서 말한대로 1을 물건의 번호만큼 << shift연산 후 or 연산을 해보자. 1을 물건의 번호인 '0'만큼 shift연산을 하게되면, 0001이 될 것이다. 1은 2진수로 0001이기 때문에 ! 그 후, 0000과 0001을 or 연산을 하면 '0'번 물건을 주웠습니다 라고 표시할 수 있는 비트가 생성되는 것이다. '1'번 물건을 줍게 되면, 1을 '1'번만큼 << shift연산을 하게되면 0001 → 0010 이 되고, 이 후 or 연산을 하게 되면 0010 이 되는 것이다. 이런식으로 x번 물건을 주웠는지 안주웠는지를 체크를 해주면서 탐색을 진행하면 된다. 3) 위에서는 비트마스크를 이용한 풀이를 알아보았다. 본인은 또 한가지 방법으로 풀이를 해보았는데, 이 방법은 모든 물건에 순서를 만들어 주는 것이다. 물건을 주울 순서를 정한 후, 해당 물건을 순서대로 주워보고 걸리는 시간 중 최소값을 찾는 방식이다. 따라서 이 풀이에는 '순열'을 구현하는 과정이 들어간다. 순열을 구현하는 방법을 모른다면 아래의 글을 읽고 오자 ! [ 순열 구현하기 (Click) ] 각 물건들의 순서를 정해주고, BFS 탐색으로 시작점 → 순서가 정해진 물건들을 순서대로 줍기 → 도착점 으로 가는 시간들 중, 최소 시간을 정답으로 채택하는 방식이다. 주의해야 할 부분은 주워야 할 물건의 갯수가 0개일 때가 존재한다. 따라서, 0 개일 때는, 시작점에서 도착점으로 바로 탐색을 해줘야 하는 것이다. [ 비트마스크 풀이 소스코드 ] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 #include < iostream > #include < queue > #define endl ” ” #define MAX 50 using namespace std ; int N, M, Bit; char MAP[MAX][MAX]; bool Visit[MAX][MAX][ 35 ]; int dx[] = { 0 , 0 , 1 , – 1 }; int dy[] = { 1 , – 1 , 0 , 0 }; pair < int , int > Start, End; void Input() { int Idx = 0 ; cin > > M > > N; for ( int i = 0 ; i < N; i + + ) { for ( int j = 0 ; j < M; j + + ) { cin > > MAP[i][j]; if (MAP[i][j] = = ‘S’ ) { Start.first = i; Start.second = j; } else if (MAP[i][j] = = ‘X’ ) { MAP[i][j] = (Idx + + ) + ‘0’ ; } } } Bit = ( 1 < < Idx) - 1 ; } void Solution() { queue < pair < pair < int , int > , pair < int , int > > > Q; Q.push( make_pair ( make_pair (Start.first, Start.second), make_pair ( 0 , 0 ))); Visit[Start.first][Start.second][ 0 ] = true ; while (Q.empty() = = 0 ) { int x = Q. front ().first.first; int y = Q. front ().first.second; int Cnt = Q. front ().second.first; int Bit_State = Q. front ().second.second; Q. pop (); if (MAP[x][y] = = ‘E’ & & Bit_State = = Bit) { cout < < Cnt < < endl ; return ; } for ( int i = 0 ; i < 4 ; i + + ) { int nx = x + dx[i]; int ny = y + dy[i]; int nB = Bit_State; if (nx > = 0 & & ny > = 0 & & nx < N & & ny < M) { if ( '0' < = MAP[nx][ny] & & MAP[nx][ny] < '5' ) { nB = Bit_State | ( 1 < < MAP[nx][ny] - '0' ); if (Visit[nx][ny][nB] = = false ) { Visit[nx][ny][nB] = true ; Q.push( make_pair ( make_pair (nx, ny), make_pair (Cnt + 1 , nB))); } } else if (MAP[nx][ny] ! = '#' ) { if (Visit[nx][ny][nB] = = false ) { Visit[nx][ny][nB] = true ; Q.push( make_pair ( make_pair (nx, ny), make_pair (Cnt + 1 , nB))); } } } } } } void Solve() { Input(); Solution(); } int main( void ) { ios::sync_with_stdio( false ); cin .tie( NULL ); cout .tie( NULL ); //freopen("Input.txt", "r", stdin); Solve(); return 0 ; } Colored by Color Scripter cs [ 순열을 통한 풀이 소스코드 ] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 #include < iostream > #include < queue > #include < vector > #include < cstring > #define endl ” ” #define MAX 50 using namespace std ; int N, M, Answer = 987654321 ; char MAP[MAX][MAX]; bool Visit[MAX][MAX]; bool Select[ 5 ]; int dx[] = { 0 , 0 , 1 , – 1 }; int dy[] = { 1 , – 1 , 0 , 0 }; vector < pair < int , int > > V, Order; pair < int , int > Start, End; int Min( int A, int B) { if (A < B) return A; return B; } void Input() { cin > > M > > N; for ( int i = 0 ; i < N; i + + ) { for ( int j = 0 ; j < M; j + + ) { cin > > MAP[i][j]; if (MAP[i][j] = = ‘X’ ) { V. push_back ( make_pair (i, j)); MAP[i][j] = ‘.’ ; } else if (MAP[i][j] = = ‘S’ ) { Start.first = i; Start.second = j; MAP[i][j] = ‘.’ ; } else if (MAP[i][j] = = ‘E’ ) { End.first = i; End.second = j; MAP[i][j] = ‘.’ ; } } } } int BFS( int Sx, int Sy, int Ex, int Ey) { memset(Visit, false , sizeof (Visit)); queue < pair < pair < int , int > , int > > Q; Q.push( make_pair ( make_pair (Sx, Sy), 0 )); Visit[Sx][Sy] = true ; while (Q.empty() = = 0 ) { int x = Q. front ().first.first; int y = Q. front ().first.second; int Cnt = Q. front ().second; Q. pop (); if (x = = Ex & & y = = Ey) return Cnt; for ( int i = 0 ; i < 4 ; i + + ) { int nx = x + dx[i]; int ny = y + dy[i]; if (nx > = 0 & & ny > = 0 & & nx < N & & ny < M) { if (MAP[nx][ny] = = '.' & & Visit[nx][ny] = = false ) { Visit[nx][ny] = true ; Q.push( make_pair ( make_pair (nx, ny), Cnt + 1 )); } } } } } void Calculate() { int S = Order. size (); int Dist = BFS(Start.first, Start.second, Order[ 0 ].first, Order[ 0 ].second); for ( int i = 0 ; i < S - 1 ; i + + ) { Dist = Dist + BFS(Order[i].first, Order[i].second, Order[i + 1 ].first, Order[i + 1 ].second); } Dist = Dist + BFS(Order[S - 1 ].first, Order[S - 1 ].second, End.first, End.second); Answer = Min(Answer, Dist); } void DFS( int Cnt) { if (Cnt = = V. size ()) { Calculate(); return ; } for ( int i = 0 ; i < V. size (); i + + ) { if (Select[i] = = true ) continue ; Select[i] = true ; Order. push_back (V[i]); DFS(Cnt + 1 ); Order.pop_back(); Select[i] = false ; } } void Solution() { if (V. size () = = 0 ) { Answer = BFS(Start.first, Start.second, End.first, End.second); cout < < Answer < < endl ; return ; } DFS( 0 ); cout < < Answer < < endl ; } void Solve() { Input(); Solution(); } int main( void ) { ios::sync_with_stdio( false ); cin .tie( NULL ); cout .tie( NULL ); //freopen("Input.txt", "r", stdin); Solve(); return 0 ; } Colored by Color Scripter cs 백준 17244번 아맞다우산 문제 링크입니다: https://www.acmicpc.net/problem/17244 비트마스킹을 통해 아이템을 주웠는지 판별해야하는 흥미로운 BFS 문제였습니다. 물건 ‘X’ 마다 각각 고유 인덱스를 부여하여 비트 연산을 통해 주웠는지를 판별하는 것이 핵심이였습니다. 물건은 최대 5개이기 때문에 인덱스는 최대 4이고 0 ~ 4 까지 모두 표시하기 위해서는 크기가 2^5 즉, 32인 배열이 필요합니다. 물건을 줍는 과정에서 같은 칸을 밟을 수 있기 때문에 평소처럼 이차원 visited 배열을 사용하면 안되고 어떤 물건을 주웠는가까지 표시하는 삼차원 visited 배열을 사용해야했습니다. 따라서, visited 배열을 visited[MAX][MAX][1 << MAX_STUFF] 로 표시했습니다. BFS 탐색을 진행할 때는 다음 칸에 줍지 않은 물건 여부를 확인한 뒤 1. 줍지 않은 물건이 있다면 checked 변수에 비트 연산을 통해 주웠다고 표시하고 큐에 넣습니다. 2. 줍지 않은 물건이 없고 갈 수 있는 칸이라면 그대로 큐에 넣습니다. 3. 모든 물건을 주웠고 도착점에 도착한다면 time을 출력하고 프로그램을 종료합니다. 문제 조건에 모든 물건을 챙길 수 없는 경우는 주어지지 않는다. 라고 나와있기 때문에 해당 부분에 대해서는 예외처리를 하지 않았습니다. 개발환경:Visual Studio 2017 지적, 조언, 질문 환영입니다! 댓글 남겨주세요~ 반응형 [백준][C++] 17244 아맞다우산 반응형 www.acmicpc.net/problem/17244 알고리즘 종류 – 구현 – BFS 사고 과정 – 이 문제에서 중요한 조건은 재방문 처리이다. 특히 아래와 같은 상황이다. 시작점 S에서 빨간색 선으로 이동하고, 초록색선으로 이동한다. 이 때 초록색 화살표 끝의 X에서는 어떻게 재방문을 처리해야 할까? – 일단, X를 구별할 수 없으니 번호를 붙여주기로 했다. – 이제 비교해볼 상황이 있다. 1. 0을 방문했고 다시 0으로 오는 경우 2. 0을 방문했고 1을 방문한 뒤에 다시 0으로 오는 경우 – 위 2가지 경우에서 1번은 재방문을 할 수 없다. 그러나 2번은 재방문을 할 수 있다. 왜냐하면, 위 이미지에서 빨간색과 초록색 경로에 해당하는 경우이기 때문이다. 이런 재방문을 어떻게 처리할 수 있을까? Bit mask를 이용하면 쉽게 해결할 수 있다. 이 문제를 풀어보면 이해하기 쉬울 것이다. – 2가지 경우를 비트로 나타내보자. 재방문 검사 배열은 isVisited[y][x][1< #include < vector > #include < queue > #include < cstring > #include < string > using namespace std ; struct State{ int y, x; int bits = 0 ; int time = 0 ; }; int h, w; int sy, sx; int totalBits = 0 ; char mat[ 51 ][ 51 ]; int isVisited[ 51 ][ 51 ][ 1 < < 6 ]; int dir[ 4 ][ 2 ] = {{ 1 , 0 }, { 0 , 1 }, { - 1 , 0 }, { 0 , - 1 }}; bool isValid( int y, int x){ return (y > = 0 & & y < h) & & (x > = 0 & & x < w); } void solution(){ queue < State > q; // y, x , X의 bit의 합, 이동 시간 State s; s.y = sy; s.x = sx; q.push(s); while ( ! q.empty()){ State cs = q. front (); q. pop (); int cy = cs.y; int cx = cs.x; int ct = cs.time; int cb = cs.bits; for ( int d = 0 ; d < 4 ; d + + ){ int ny = cy + dir[d][ 0 ]; int nx = cx + dir[d][ 1 ]; // 모든 물건을 가지고 문에 도착하면 종료 if (mat[ny][nx] = = 'E' & & cb = = totalBits){ cout < < ct + 1 ; return ; } if ( ! isValid(ny, nx)) continue ; // 물건에 도착하면 if (mat[ny][nx] > = ‘0’ & & mat[ny][nx] < '5' ){ // 같은 물건을 가지고 같은 자리에 왔었는지 확인 int nb = cb | ( 1 < < mat[ny][nx] - '0' ); if ( ! isVisited[ny][nx][nb]){ isVisited[ny][nx][nb] = 1 ; State ns; ns.y = ny; ns.x = nx; ns.time = ct + 1 ; ns.bits = nb; q.push(ns); } } // 일반, 출입구, 시작점을 지나는 경우 // 출구가 그래프의 가운데 있을 수도 있어서 지나칠 수 있다. else if (mat[ny][nx] ! = '#' ){ if ( ! isVisited[ny][nx][cb]){ isVisited[ny][nx][cb] = 1 ; State ns; ns.y = ny; ns.x = nx; ns.time = ct + 1 ; ns.bits = cb; q.push(ns); } } } } } int main( void ){ ios_base::sync_with_stdio( 0 ); cin .tie( 0 ); cin > > w > > h; char mark = ‘0’ ; for ( int i = 0 ; i < h; i + + ){ for ( int j = 0 ; j < w; j + + ){ cin > > mat[i][j]; if (mat[i][j] = = ‘S’ ){ sy = i; sx = j; mat[i][j] = ‘.’ ; } else if (mat[i][j] = = ‘X’ ){ mat[i][j] = mark + + ; // X에 번호를 붙여준다. } } } // 모든 X를 더했을 때 최종 값을 구한다. // X가 3까지면 2^4-1이 최종 값이 된다. totalBits = ( 1 < < mark - '0' ) - 1 ; solution(); } Colored by Color Scripter cs 시행착오 - 첫 시도는 메모리 초과였다. 본인은 우선순위 큐를 이용해서 X를 방문한 개수 내림차순, 이동시간 오름차순으로 데이터를 저장하여 가장 먼저 X를 방문하면서 최단 시간을 찾으려고 했다. 그런데 재방문 처리를 하지 않았다. 제출에서 50%가 되면서 메모리 초과가 발생했다. - 배운 것이 있다면, 우선순위 큐에 compare를 만들어서 사용하는 방법이다. 아래에 시도했던 코드가 있다. 더보기 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 #include < iostream > #include < vector > #include < queue > #include < cstring > #include < string > using namespace std ; struct State{ int cnt = 0 ; int time = 0 ; int y, x; string check = “00000” ; }; struct cmp{ bool operator ()(State a, State b){ if (a.cnt ! = b.cnt) return a.cnt < b.cnt; else return a.time > b.time; } }; int h, w; int sy, sx, ey, ex; int thingCnt = 0 ; int answer = 0 ; char mat[ 51 ][ 51 ]; int isVisited[ 51 ][ 51 ]; int dir[ 4 ][ 2 ] = {{ 1 , 0 }, { 0 , 1 }, { – 1 , 0 }, { 0 , – 1 }}; vector < pair < int , int > > things; bool isValid( int y, int x){ return (y > = 0 & & y < h) & & (x > = 0 & & x < w); } void solution(){ priority_queue < State, vector < State > , cmp > pq; State s; s.y = sy; s.x = sx; pq.push(s); while ( ! pq.empty()){ State cs = pq.top(); pq. pop (); int cy = cs.y; int cx = cs.x; int ct = cs.time; int cc = cs.cnt; string cch = cs.check; for ( int d = 0 ; d < 4 ; d + + ){ int ny = cy + dir[d][ 0 ]; int nx = cx + dir[d][ 1 ]; if (mat[ny][nx] = = 'E' & & cc = = thingCnt){ answer = ct + 1 ; return ; } if ( ! isValid(ny, nx)) continue ; if (mat[ny][nx] = = '#' ) continue ; if (mat[ny][nx] > = ‘0’ & & mat[ny][nx] < '5' ){ int num = mat[ny][nx] - '0' ; if (cs.check[num] = = '0' ){ State ns; ns.y = ny; ns.x = nx; ns.cnt = cc + 1 ; ns.time = ct + 1 ; ns.check = cch; ns.check[num] = '1' ; pq.push(ns); } else { State ns; ns.y = ny; ns.x = nx; ns.cnt = cc; ns.time = ct + 1 ; ns.check = cch; pq.push(ns); } } else { State ns; ns.y = ny; ns.x = nx; ns.cnt = cc; ns.time = ct + 1 ; ns.check = cch; pq.push(ns); } } } } int main( void ){ ios_base::sync_with_stdio( 0 ); cin .tie( 0 ); cin > > w > > h; int mark = ‘0’ ; for ( int i = 0 ; i < h; i + + ){ for ( int j = 0 ; j < w; j + + ){ cin > > mat[i][j]; if (mat[i][j] = = ‘S’ ){ sy = i; sx = j; mat[i][j] = ‘.’ ; } else if (mat[i][j] = = ‘E’ ){ ey = i; ex = j; } else if (mat[i][j] = = ‘X’ ){ things. push_back ({i,j}); mat[i][j] = mark; mark + + ; thingCnt + + ; } } } solution(); cout < < answer < < endl ; } Colored by Color Scripter cs - 골드 3이상이 되면서 재방문 조건이 까다로워 지고 있다. 이번 문제에서는 비트 마스크를 이용한 재방문 조건 생성이다. A지점을 방문할 때, A에서 A로 오는 재방문은 방지 하지만, A에서 B를 갔다가 다시 A로 오는 재방문은 허락한다. 반응형 So you have finished reading the 아 맞다 우산 topic article, if you find this article useful, please share it. Thank you very much. See more: 백준 빡 구현

[백준][C++] 17244 아맞다우산

반응형

www.acmicpc.net/problem/17244

알고리즘 종류

– 구현

– BFS

사고 과정

– 이 문제에서 중요한 조건은 재방문 처리이다. 특히 아래와 같은 상황이다. 시작점 S에서 빨간색 선으로 이동하고, 초록색선으로 이동한다. 이 때 초록색 화살표 끝의 X에서는 어떻게 재방문을 처리해야 할까?

– 일단, X를 구별할 수 없으니 번호를 붙여주기로 했다.

– 이제 비교해볼 상황이 있다.

1. 0을 방문했고 다시 0으로 오는 경우

2. 0을 방문했고 1을 방문한 뒤에 다시 0으로 오는 경우

– 위 2가지 경우에서 1번은 재방문을 할 수 없다. 그러나 2번은 재방문을 할 수 있다. 왜냐하면, 위 이미지에서 빨간색과 초록색 경로에 해당하는 경우이기 때문이다. 이런 재방문을 어떻게 처리할 수 있을까? Bit mask를 이용하면 쉽게 해결할 수 있다. 이 문제를 풀어보면 이해하기 쉬울 것이다.

– 2가지 경우를 비트로 나타내보자. 재방문 검사 배열은 isVisited[y][x][1< #include < vector > #include < queue > #include < cstring > #include < string > using namespace std ; struct State{ int y, x; int bits = 0 ; int time = 0 ; }; int h, w; int sy, sx; int totalBits = 0 ; char mat[ 51 ][ 51 ]; int isVisited[ 51 ][ 51 ][ 1 < < 6 ]; int dir[ 4 ][ 2 ] = {{ 1 , 0 }, { 0 , 1 }, { - 1 , 0 }, { 0 , - 1 }}; bool isValid( int y, int x){ return (y > = 0 & & y < h) & & (x > = 0 & & x < w); } void solution(){ queue < State > q; // y, x , X의 bit의 합, 이동 시간 State s; s.y = sy; s.x = sx; q.push(s); while ( ! q.empty()){ State cs = q. front (); q. pop (); int cy = cs.y; int cx = cs.x; int ct = cs.time; int cb = cs.bits; for ( int d = 0 ; d < 4 ; d + + ){ int ny = cy + dir[d][ 0 ]; int nx = cx + dir[d][ 1 ]; // 모든 물건을 가지고 문에 도착하면 종료 if (mat[ny][nx] = = 'E' & & cb = = totalBits){ cout < < ct + 1 ; return ; } if ( ! isValid(ny, nx)) continue ; // 물건에 도착하면 if (mat[ny][nx] > = ‘0’ & & mat[ny][nx] < '5' ){ // 같은 물건을 가지고 같은 자리에 왔었는지 확인 int nb = cb | ( 1 < < mat[ny][nx] - '0' ); if ( ! isVisited[ny][nx][nb]){ isVisited[ny][nx][nb] = 1 ; State ns; ns.y = ny; ns.x = nx; ns.time = ct + 1 ; ns.bits = nb; q.push(ns); } } // 일반, 출입구, 시작점을 지나는 경우 // 출구가 그래프의 가운데 있을 수도 있어서 지나칠 수 있다. else if (mat[ny][nx] ! = '#' ){ if ( ! isVisited[ny][nx][cb]){ isVisited[ny][nx][cb] = 1 ; State ns; ns.y = ny; ns.x = nx; ns.time = ct + 1 ; ns.bits = cb; q.push(ns); } } } } } int main( void ){ ios_base::sync_with_stdio( 0 ); cin .tie( 0 ); cin > > w > > h; char mark = ‘0’ ; for ( int i = 0 ; i < h; i + + ){ for ( int j = 0 ; j < w; j + + ){ cin > > mat[i][j]; if (mat[i][j] = = ‘S’ ){ sy = i; sx = j; mat[i][j] = ‘.’ ; } else if (mat[i][j] = = ‘X’ ){ mat[i][j] = mark + + ; // X에 번호를 붙여준다. } } } // 모든 X를 더했을 때 최종 값을 구한다. // X가 3까지면 2^4-1이 최종 값이 된다. totalBits = ( 1 < < mark - '0' ) - 1 ; solution(); } Colored by Color Scripter cs 시행착오 - 첫 시도는 메모리 초과였다. 본인은 우선순위 큐를 이용해서 X를 방문한 개수 내림차순, 이동시간 오름차순으로 데이터를 저장하여 가장 먼저 X를 방문하면서 최단 시간을 찾으려고 했다. 그런데 재방문 처리를 하지 않았다. 제출에서 50%가 되면서 메모리 초과가 발생했다. - 배운 것이 있다면, 우선순위 큐에 compare를 만들어서 사용하는 방법이다. 아래에 시도했던 코드가 있다. 더보기 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 #include < iostream > #include < vector > #include < queue > #include < cstring > #include < string > using namespace std ; struct State{ int cnt = 0 ; int time = 0 ; int y, x; string check = “00000” ; }; struct cmp{ bool operator ()(State a, State b){ if (a.cnt ! = b.cnt) return a.cnt < b.cnt; else return a.time > b.time; } }; int h, w; int sy, sx, ey, ex; int thingCnt = 0 ; int answer = 0 ; char mat[ 51 ][ 51 ]; int isVisited[ 51 ][ 51 ]; int dir[ 4 ][ 2 ] = {{ 1 , 0 }, { 0 , 1 }, { – 1 , 0 }, { 0 , – 1 }}; vector < pair < int , int > > things; bool isValid( int y, int x){ return (y > = 0 & & y < h) & & (x > = 0 & & x < w); } void solution(){ priority_queue < State, vector < State > , cmp > pq; State s; s.y = sy; s.x = sx; pq.push(s); while ( ! pq.empty()){ State cs = pq.top(); pq. pop (); int cy = cs.y; int cx = cs.x; int ct = cs.time; int cc = cs.cnt; string cch = cs.check; for ( int d = 0 ; d < 4 ; d + + ){ int ny = cy + dir[d][ 0 ]; int nx = cx + dir[d][ 1 ]; if (mat[ny][nx] = = 'E' & & cc = = thingCnt){ answer = ct + 1 ; return ; } if ( ! isValid(ny, nx)) continue ; if (mat[ny][nx] = = '#' ) continue ; if (mat[ny][nx] > = ‘0’ & & mat[ny][nx] < '5' ){ int num = mat[ny][nx] - '0' ; if (cs.check[num] = = '0' ){ State ns; ns.y = ny; ns.x = nx; ns.cnt = cc + 1 ; ns.time = ct + 1 ; ns.check = cch; ns.check[num] = '1' ; pq.push(ns); } else { State ns; ns.y = ny; ns.x = nx; ns.cnt = cc; ns.time = ct + 1 ; ns.check = cch; pq.push(ns); } } else { State ns; ns.y = ny; ns.x = nx; ns.cnt = cc; ns.time = ct + 1 ; ns.check = cch; pq.push(ns); } } } } int main( void ){ ios_base::sync_with_stdio( 0 ); cin .tie( 0 ); cin > > w > > h; int mark = ‘0’ ; for ( int i = 0 ; i < h; i + + ){ for ( int j = 0 ; j < w; j + + ){ cin > > mat[i][j]; if (mat[i][j] = = ‘S’ ){ sy = i; sx = j; mat[i][j] = ‘.’ ; } else if (mat[i][j] = = ‘E’ ){ ey = i; ex = j; } else if (mat[i][j] = = ‘X’ ){ things. push_back ({i,j}); mat[i][j] = mark; mark + + ; thingCnt + + ; } } } solution(); cout < < answer < < endl ; } Colored by Color Scripter cs - 골드 3이상이 되면서 재방문 조건이 까다로워 지고 있다. 이번 문제에서는 비트 마스크를 이용한 재방문 조건 생성이다. A지점을 방문할 때, A에서 A로 오는 재방문은 방지 하지만, A에서 B를 갔다가 다시 A로 오는 재방문은 허락한다. 반응형

[백준/17244/파이썬] 아 맞다 ! 우산

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

Problem

경재씨는 저녁 약속을 가기 전 챙기지 않은 물건들이 있는 지 확인하고 있다. 필요한 물건은 전부 챙긴 것 같았고 외출 후 돌아오는 길에 경재씨는 외쳤다. “아 맞다 우산!!!”

외출이 잦은 경재 씨는 반복되는 일을 근절하기 위해 꼭 챙겨야 할 물건들을 정리해보았다. 하지만 지갑, 스마트폰, 우산, 차 키, 이어폰, 시계, 보조 배터리 등 종류와 개수가 너무 많았다.

경재 씨는 한 걸음에 상하좌우에 인접한 칸으로만 움직일 수 있다.

경재 씨를 위해 집을 위에서 바라본 모습과 챙겨야 할 물건들의 위치들을 알고 있을 때, 물건을 모두 챙겨서 외출하기까지 최소 몇 걸음이 필요한지 구하는 프로그램을 작성하자.

조건

첫 번째 줄에는 집의 가로 길이 N과 세로 길이 M이 입력된다. (3 ≤ N, M ≤ 50)

두 번째 줄부터는 집의 구조가 예제 입력과 같이 주어진다.

비어있는 곳은 ‘.’로 벽은 ‘#’로 입력된다. 경재 씨의 현재 위치는 S, 나가는 문의 위치는 E, 챙겨야 하는 물건은 종류에 상관없이 X로 입력된다.

챙겨야 하는 물건은 최대 5개까지 있을 수 있다. 집은 언제나 벽으로 둘러싸여 있고, 나가는 문은 언제나 하나이다.

SOL

굉장히 쉬워보였는데, 재방문 여부 때문에, 어려웠던 문제이다. Troblue Shooting 된 부분을 보겠음!

예제에서 첫번째 줄만 봐도, 바로 통상적인 BFS만 쓰면 문제가 발생한다는걸 바로 느낄 수 있다.

그림판

주황색 부분에서 -> 하늘색 부분으로 간다고 생각해보자.

첫번째 문제점. 재방문을 처리해줄 수가 없다.

주황색을 들렸다가 -> 하늘색을 들리고 -> 어쩔 수 없이 다시 주황색을 들려야한다.( 재방문이 일어난다 )

) 하지만, 주황색을 재방문하는 경우는 2가지를 생각해줄 수 있게 된다. 주황색을 줍고 -> 하늘색을 줍고 -> 재방문 하는 경우 (O) => 우리가 원하는 경우 주황색을 줍고 -> 한칸 갔다가 -> 다시 주황색을 재방문하는 경우 (X) => 우리가 원하지 않는 경우

이때, 통상적인 방문체크대로 하면, 하늘색에서 주황색으로 돌아올 수 없게 된다.(방문했던 곳은 재방문을 하지 않기 때문에) ,그리고 지금은 일직선이라서 그렇지, 주황색 ->하늘색이 최소일 수도 있고, 하늘색 ->주황색이 최소일 수도 있다.

결론적으로, “S”를 기준으로 가장 가까이 있는 거리로, “X”들을 줍겠지만, 재방문이 일어날 시 에, 그 거리들의 합은 최소거리가 아니게 될 뿐더러, 다 못줍는 경우도 생기게 되는게 문제이다.

두번째 문제점. “X”가 있는 곳에서 이전 상태의 정보를 알아야한다.

그리고, 또 문제점이 내가 “X”가 있는 곳에서 그 이전 상태의 정보가 하나도 반영이 되지 않는다는게 문제다.

통상적인 BFS를 쓰게 된다면, “S”를 기준으로 최단거리에 있을 뿐, 내가 파랑 -> 빨강 ->분홍 ->주황 등 어떤 공을 주웠는지에 대한 정보가 하나도 담겨있지 않게 된다. 그래서, 주운 갯수의 정보로 코드를 구현하게 되어도, 각각 위치가 다르기 때문에, 의미가 없게 된다.

즉, 모든 “X”들을 구분지을 필요가 있어졌고, “X”들이 내가 현재 주운 상태인지 아닌지를 확인할 방법이 필요하게 된다. 사실 이 부분의 아이디어는 내가 공부하지 못했던, “비트 마스킹”이라는 개념을 활용하게 되었다.

간단하게, 비트마스킹은, 비트로 내 상태를 저장하게 되는 개념인데, 위처럼 어떤 연속적인 상태를 저장해야할 때, 저장공간을 규칙적(논리적)으로 만드는 개념이다.

파랑공 : 1 , 빨강공 : 2 , 분홍공 :3 주황공 :4 이라고 할때, 0000으로 치환해서,파랑공을 주웠으면, 0001,빨강공을 주웠으면 ,0010, 분홍공을 주웠으면 0100, 주황공을 주웠으면 1000 이라고 가정하고, 1111이 되면 다 주웠다고 생각을 하면된다. (사실 비트가 아니라, 파랑,빨강,분홍,주황에 숫자를 부여하고, 1234가 되었을때 처럼 숫자로 생각해줘도 상관은 없다)

, , 1<<공들의 숫자로 하게 되면, 이제부터 우리는 어떤 공을 주웠는지, 줍지않았는지에 대한 정보를 알 수 있게 된다. 정리 우리가 원하는 것만 걸러주기 위해서, 어떻게 비트마스킹을 응용하면 되나면, visited배열에 주운 정보를 3차원으로 저장해주면 된다! 그 공을 주운자리로 또 되돌아가면 안되기 때문에, 주운상태에서는 , 새로운 방문배열이 생기는 것처럼 생각해주면 된다! (사실 처음에 이걸 만들어 주려다가, "X"를 방문할 때마다, 방문배열을 새로 만들어주니까, 그 이전 정보들이 날아가게 되서, 왔던 곳을 다시 방문하게되는 불상사가 일어나게 되버렸다) 주황색을 줍고 -> 하늘색을 줍고 -> 재방문 하는 경우 (O) => 우리가 원하는 경우

주황색을 줍고 -> 한칸 갔다가 -> 다시 주황색을 재방문하는 경우 (X) => 우리가 원하지 않는 경우

그래서, 공들의 번호를 그냥 발견되는 차례대로 0~n-1번까지 붙이고, “X”를 방문할 때마다, bit 정보랑 |연산을 계속해주면서, 탈출지점에 도달 했을 때, 공을 모두 주운 상태라면, 그 중에 최소 거리를 반영해주면 된다.

# 아 맞다! 우산! # 비트 마스킹 import sys from collections import deque input= sys.stdin.readline M,N =map(int,input().split()) board=[] #visited[y][x][bit] #11111(5개)는 32이므로, 32 까지해줘도됨. visited=[[[0 for _ in range(35)] for _ in range(M)] for _ in range(N)] dy=[0,1,0,-1] dx=[1,0,-1,0] sy,sx=0,0 #공 번호 저장 pos_X=[] ans=sys.maxsize for i in range(N): tmp=input().rstrip() for j in range(M): if tmp[j]==”S”: sy,sx=i,j elif tmp[j]==”X”: pos_X.append((i,j)) board.append(tmp) def solve(y,x): global ans dq=deque() dq.append((y,x,0,0)) visited[y][x][0] =1 while dq: y,x,bit,d=dq.popleft() # d가 현재 최솟값보다 크다면, 굳이 이 과정을 해줄 필요가 없다. if d

키워드에 대한 정보 아 맞다 우산

다음은 Bing에서 아 맞다 우산 주제에 대한 검색 결과입니다. 필요한 경우 더 읽을 수 있습니다.

이 기사는 인터넷의 다양한 출처에서 편집되었습니다. 이 기사가 유용했기를 바랍니다. 이 기사가 유용하다고 생각되면 공유하십시오. 매우 감사합니다!

사람들이 주제에 대해 자주 검색하는 키워드 [천관사복] 진옥으로 비교당하는 아이

  • 동영상
  • 공유
  • 카메라폰
  • 동영상폰
  • 무료
  • 올리기
[천관사복] #진옥으로 #비교당하는 #아이


YouTube에서 아 맞다 우산 주제의 다른 동영상 보기

주제에 대한 기사를 시청해 주셔서 감사합니다 [천관사복] 진옥으로 비교당하는 아이 | 아 맞다 우산, 이 기사가 유용하다고 생각되면 공유하십시오, 매우 감사합니다.

See also  서울 게임 아카데미 현실 | 게임 학원.. 프로게이머 학원.. 롤 학원.. 100% 솔직 후기 55 개의 자세한 답변

Leave a Reply

Your email address will not be published. Required fields are marked *