• 카테고리

    질문 & 답변
  • 세부 분야

    알고리즘 · 자료구조

  • 해결 여부

    미해결

3-C 인구이동 코드 질문

23.09.14 15:44 작성 23.09.14 15:55 수정 조회수 105

0

코드에 대한 질문이 있습니다.

아래는 제가 짠 코드입니다.

다른 부분은 볼 필요 없이 dfs(i, j) 이 부분에 대한 궁금증이 있습니다.

저는 dfs(i, j) ... void dfs(int y, int x)이런식으로 짰는데

강사님 코드를 보면 dfs(i, j, v) ... void dfs(int y, int x, vector<pair<int,int>> &v) 이런식으로 줬습니다.

이렇게 짜야하는 이유가 궁금합니다.

 

이에 대한 제 예상 해답은

벡터에 call by reference를 적용했기 때문인데 왜 call by reference를 적용해야하는지를 모르겠습니다.

벡터에 call by reference를 적용한다고 치면 void dfs 안에 있는 다른 변수들(sum, cnt) 같은 변수들도 dfs(i, j, sum, cnt) 이런식으로 줘야하는것이 아닌가요?

call by value, call by reference 부분 교안을 봐도 이해가 되지 않아서 질문드립니다. 자세한 답변 부탁드립니다

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

const int dy[4] = { -1 ,0, 1, 0 };
const int dx[4] = { 0, 1, 0, -1 };

int n, l, r, a[55][55], visited[55][55], sum, cnt;
vector<pair<int, int>> v;

void dfs(int y, int x) {
  visited[y][x] = 1;
  for (int i = 0; i < 4; i++) {
	int ny = y + dy[i];
	int nx = x + dx[i];
	if (ny < 0 || ny >= n || nx < 0 || nx >= n) continue;
	if (visited[ny][nx]) continue;
	if (abs(a[y][x] - a[ny][nx]) >= l && abs(a[y][x] - a[ny][nx]) <= r) {
	  v.push_back({ ny, nx });
	  sum += a[ny][nx];
	  cnt++;
	  dfs(ny, nx);
	}
  }
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL); cout.tie(NULL);

  cin >> n >> l >> r;
  for (int i = 0; i < n; i++) {
	for (int j = 0; j < n; j++) {
	  cin >> a[i][j];
	}
  }
  int ret = 0;
  while (true) {
	int flag = 0;
	fill(&visited[0][0], &visited[0][0] + 55 * 55, 0);
	for (int i = 0; i < n; i++) {
	  for (int j = 0; j < n; j++) {
		if (visited[i][j]) continue;
		v.clear();
		visited[i][j] = 1;
		v.push_back({ i, j });
		cnt = 1;
		sum = a[i][j];
		//1. 왜 여기 dfs에서 dfs(i, j, v)로 줘야하는지?
		//2. 만약 이에 대한 해답이 call by reference 이면
		//위에 따로 빼놓은 dfs 함수 부분에서
		//sum, cnt 이런 변수들도 똑같이 dfs(i, j, sum, cnt) 이런식으로 넣어줘야 하는 것이 아닌지?
		dfs(i, j);
		if (cnt == 1) continue;
		for (pair<int, int> b : v) {
		  a[b.first][b.second] = sum / cnt;
		  flag = 1;
		}
	  }
	}
	if (!flag) break;
	ret++;
  }
  cout << ret << '\n';


  return 0;
}

 

 

답변 1

답변을 작성해보세요.

0

안녕하세요 firdoo님 ㅎㅎ

강사님 코드를 보면 dfs(i, j, v) ... void dfs(int y, int x, vector<pair<int,int>> &v) 이런식으로 줬습니다.

이렇게 짜야하는 이유가 궁금합니다.

>> 이렇게 굳이 안짜도 무방합니다. 수강생님코드도 괜찮습니다.

 

벡터에 call by reference를 적용했기 때문인데 왜 call by reference를 적용해야하는지를 모르겠습니다.

>> 수강생님 코드를 보시면 전역변수로 선언했기 때문에 딱히 매개변수로 넣지 않아도 됩니다.

제 코드 또한 전역변수로 선언했기 때문에 배열에 매개변수로 넣지 않았다면 굳이 call by reference로 넣지 않아도 됩니다.

vector<pair<int, int>> v;  

 

만약 매개변수로 넘기는 코드로 작성하고 또한 매개변수로 넘겨서 해당 벡터에 변화를 주고 싶은 경우 call by reference로 넘겨야 합니다.

코드를 보면 다음과 같이 push_back을 하고 있기 때문에 call by reference로 넘겨야 합니다.

void dfs(int y,int x,vector<pair<int,int>> &v){
    visited[y][x] = 1;
    v.push_back({y,x});

 

벡터에 call by reference를 적용한다고 치면 void dfs 안에 있는 다른 변수들(sum, cnt) 같은 변수들도 dfs(i, j, sum, cnt) 이런식으로 줘야하는것이 아닌가요?

>> 꼭 그렇게 주어야 하는 것은 아니고 그렇게 sum, cnt를 넘기는 식으로 만들 수는 있습니다.

sum부분을 보시면. 다음과 같이 함수바깥에서 전역변수인 sum에 다른 값을 할당하는 것을 볼 수 있습니다.

                    v.push_back({i,j});
                    sum = a[i][j];

 

call by value, call by reference 부분 교안을 봐도 이해가 되지 않아서 질문드립니다. 자세한 답변 부탁드립니다

>> 아마 제 생각에 전역변수를 매개변수로 넘기는 부분에 있어서 헷갈리시는 거 같은데요.

call by value는 원본값을 수정하지 않는다. call by reference는 원본값을 수정한다고 생각하시면 됩니다.

 

#include <bits/stdc++.h>
using namespace std; 
int add(int a, int b){
    a += 10;
    cout << a << '\n';
    return a + b; 
}
int main(){ 
    int a = 1; 
    int b = 2; 
    int sum = add(a, b);
    cout << a << '\n'; 
    return 0;
}
/* 
11
1
*/

앞의 코드를 보시면 a는 수정되지 않습니다. call by value로 넘겼기 때문입니다.

 

자 그럼 다음과 같은 코드를 볼게요.

#include <bits/stdc++.h>
using namespace std; 
int a = 1;
int add(int a){
    a += 10; 
    return a; 
}
int main(){  
    add(a);
    cout << a << '\n'; 
    return 0;
}
/*  
1
*/

이 코드는 1이 나옵니다. 어? 분명 전역변수 a를 넘긴 거 같은데?

라고 할 수 있죠.

네 하지만 call by value로 넘겼기 때문에 해당 값은 변화되지 않습니다.

만약 전역변수를 수정하고 싶다면 2가지 방법을 써야 합니다.

1.매개변수로 넣지 않는다.

#include <bits/stdc++.h>
using namespace std; 
int a = 1;
int add(){
    a += 10; 
    return a;
}
int main(){  
    add();
    cout << a << '\n'; 
    return 0;
}
/*  
11
*/
  1. call by reference로 한다.

#include <bits/stdc++.h>
using namespace std; 
int a = 1;
int add(int &a){
    a += 10; 
    return a;
}
int main(){  
    add(a);
    cout << a << '\n'; 
    return 0;
}
/*  
11
*/

 

 

또 질문 있으시면 언제든지 질문 부탁드립니다.

좋은 수강평과 별점 5점은 제게 큰 힘이 됩니다. :)

감사합니다.

강사 큰돌 올림.

firdoo님의 프로필

firdoo

질문자

2023.09.17

감사합니다!