https://www.acmicpc.net/problem/7569
tuple로 push한 queue의 원소에서, 해당 원소의 front 값을 받아와서 auto cur= Q.front(); 연산을 거치고 난뒤,
각각의 해당 원소의 x, y, z 값에 접근하기 위해서는, get<index>(tuple_name) 형태로 접근해서 개별 원소에 접근할 수 있다.
아래의 풀이는 내가 tuple의 원소에 get<index>(tuple_name) 형태로 접근해서 풀이한 풀이이다.
#include <bits/stdc++.h>
using namespace std;
int board[105][105][105];
int vis[105][105][105];
int m, n, h;
int dx[6]={0,1,0,-1,0,0};
int dy[6]={1,0,-1,0,0,0};
int dz[6]={0,0,0,0,1,-1};
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cin>> m >> n >> h;
// h먼저 받고, 나머지 m, n 순서로 받도록 하자.
for(int k=0; k<h; k++){
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
cin>>board[k][i][j];
}
}
}
bool impossilbe=false;
for(int k=0; k<h; k++){
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
if(board[k][i][j]==0){
impossilbe=true;
}
}
}
}
if(impossilbe==false){
cout<<0;
return 0;
}
queue<tuple<int,int,int>> Q;
for(int k=0; k<h; k++){
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
if(board[k][i][j]==1){
vis[k][i][j]=1;
Q.push({k,i,j});
}
}
}
}
while(!Q.empty()){
auto cur=Q.front(); Q.pop();
for(int dir=0; dir<6; dir++){
int nx=get<1>(cur)+dx[dir];
int ny=get<2>(cur)+dy[dir];
int nz=get<0>(cur)+dz[dir];
if(nx<0 || nx>=n || ny<0 || ny>=m || nz<0 || nz>=h) continue;
if(board[nz][nx][ny]==-1) continue;//비어있다면
if(vis[nz][nx][ny]!=0) continue;//이미 방문했다면
vis[nz][nx][ny]=vis[get<0>(cur)][get<1>(cur)][get<2>(cur)]+1;
Q.push({nz,nx,ny});
// cout<<"h";
}
}
for(int k=0; k<h; k++){
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
if(board[k][i][j]==-1) vis[k][i][j]=-1;
}
}
}
int mx=0;
for(int k=0; k<h; k++){
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
if(vis[k][i][j]==0) {
cout<<"-1";
return 0;
}
mx=max(mx,vis[k][i][j]);
}
}
}
cout<<mx-1;
}
tuple로 선언한 밸류의 개별 원소에 접근하는 방법에 대해서 gpt에서 찾아보면, 두가지 방법에 대한 방법을 얻을 수 있다.
이때 나는 첫번째 설명해준 get<index>(tuple_name) 방식을 사용하여 풀이하였는데, 오히려 tuple을 사용하는 경우는 tie() 함수를 사용하는 두번째 방법이 더욱 보기 간결해보이고 작성할 분량이 적어서 더 좋은것 같다. pair를 사용하는 방법은 auto cur 형태로 작성해서 first, second 접근을 하도록 하고, tuple을 사용하는 문제의 경우는 tie() 함수를 통해서 언팩킹 해보도록 하자.
C++에서 `std::tuple` 형태로 정의된 값의 개별 원소에 접근하는 방법은 다음과 같이 할 수 있습니다:
1. **사용할 헤더 파일 포함:** `std::tuple`을 사용하려면 `<tuple>` 헤더 파일을 포함해야 합니다.
2. **tuple 원소에 접근:**
- `std::get<Index>(myTuple)`: `myTuple`에서 `Index` 위치의 원소에 접근합니다.
인덱스는 0부터 시작하며, 컴파일 타임에 결정되어야 합니다.
- 예를 들어, 다음은 `std::tuple`을 정의하고 각 원소에 접근하는 예제입니다:
```cpp
#include <iostream>
#include <tuple>
int main() {
std::tuple<int, double, std::string> myTuple(42, 3.14, "Hello, World!");
int intValue = std::get<0>(myTuple); // 첫 번째 원소에 접근
double doubleValue = std::get<1>(myTuple); // 두 번째 원소에 접근
std::string stringValue = std::get<2>(myTuple); // 세 번째 원소에 접근
std::cout << "First: " << intValue << std::endl;
std::cout << "Second: " << doubleValue << std::endl;
std::cout << "Third: " << stringValue << std::endl;
return 0;
}
```
위의 예제에서는 `std::get()` 함수를 사용하여 각 원소에 접근합니다. 각 원소의 타입은
`std::tuple`을 정의할 때 지정됩니다.
3. **tie() 함수 사용:**
- `std::tie()` 함수를 사용하여 여러 변수에 동시에 `std::tuple`의 원소를 언패킹할 수도 있습니다.
이것은 특히 `std::tuple`을 사용하여 여러 값을 반환하는 경우 유용합니다.
```cpp
#include <iostream>
#include <tuple>
std::tuple<int, double, std::string> getValues() {
return std::make_tuple(42, 3.14, "Hello, World!");
}
int main() {
int intValue;
double doubleValue;
std::string stringValue;
std::tie(intValue, doubleValue, stringValue) = getValues();
std::cout << "First: " << intValue << std::endl;
std::cout << "Second: " << doubleValue << std::endl;
std::cout << "Third: " << stringValue << std::endl;
return 0;
}
```
이렇게 하면 `getValues()` 함수가 `std::tuple`을 반환하고, `std::tie()` 함수를 사용하여
원소를 변수에 할당할 수 있습니다.
이러한 방법으로 `std::tuple`의 원소에 접근할 수 있습니다.
아래 첨부할 풀이는, tie 함수를 활용한 풀이이다. 이 풀이의 경우는 tie()를 사용하는 부분도 그렇고, 내가 여러 부분으로 나누어서 삼중for문을 통해 처리하는 과정을 하나의 삼중 for문 내부로 엮어서 처리하는 등의 과정을 통해 전체적인 코드의 길이가 짧다.
이런식으로 풀이할 수 있도록 코드를 작성해보자. 다만 공간복잡도, 시간복잡도 측면에서는 큰 차이는 없다.
// Authored by : BueVonHun
// Co-authored by : BaaaaaaaaaaarkingDog
// http://boj.kr/f3877bee8d3c454482dd3229e4246b49
#include <bits/stdc++.h>
using namespace std;
int dx[6] = {0, 0, 1, -1, 0, 0};
int dy[6] = {1, -1, 0, 0, 0, 0};
int dz[6] = {0, 0, 0, 0, 1, -1};
int board[103][103][103];
int dist[103][103][103];
queue<tuple<int, int, int>> Q;
int m, n, h;
int main(void) {
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> m >> n >> h;
for (int i = 0; i < h; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < m; k++) {
int tmp;
cin >> tmp;
board[j][k][i] = tmp;
if (tmp == 1) Q.push({j, k, i});
if (tmp == 0) dist[j][k][i] = -1;
}
}
}
while (!Q.empty()) {
auto cur = Q.front();
Q.pop();
int curX, curY, curZ;
tie(curX, curY, curZ) = cur;
for (int dir = 0; dir < 6; dir++) {
int nx = curX + dx[dir];
int ny = curY + dy[dir];
int nz = curZ + dz[dir];
if (nx < 0 || nx >= n || ny < 0 || ny >= m || nz < 0 || nz >= h) continue;
if (dist[nx][ny][nz] >= 0) continue;
dist[nx][ny][nz] = dist[curX][curY][curZ] + 1;
Q.push({nx, ny, nz});
}
}
int ans = 0;
for (int i = 0; i < h; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < m; k++) {
if (dist[j][k][i] == -1) {
cout << -1 << "\n";
return 0;
}
ans = max(ans, dist[j][k][i]);
}
}
}
cout << ans << "\n";
return 0;
}
'알고리즘 > BOJ' 카테고리의 다른 글
BOJ 2468 c++ 안전 영역 (0) | 2023.09.23 |
---|---|
BOJ 2583 c++ 영역 구하기 (0) | 2023.09.22 |
BOJ 10026 c++ 적록색약 (0) | 2023.09.20 |
BOJ 1012 유기농 배추 || x 좌표와 y 좌표의 꼬임을 매우매우 조심할것. (0) | 2023.09.16 |
BOJ 7576 토마토 || 내 풀이와 거기에서 더 좋은 개선사항. (0) | 2023.09.16 |