#include <bits/stdc++.h>
using namespace std;
int ret, n;
struct Board{
int a[24][24];
void _rotate90(){
int temp[24][24];
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
temp[i][j] = a[n-j-1][i];
}
}
memcpy(a,temp,sizeof(a));
}
void _move(){
int temp[24][24];
for(int i=0; i<n; i++){
int c = -1;
int d = 0;
for(int j=0; j<n; j++){
if(a[i][j] == 0) continue;
if(d && a[i][j] == temp[i][c]) { // c가 -1이어도 인덱스아웃이 안나네..?
temp[i][c] *= 2;
d = 0;
}else{
temp[i][++c] = a[i][j];
d = 1;
}
}
for(c++; c<n; c++) temp[i][c] = 0;
}
memcpy(a,temp,sizeof(a));
}
void get_max(){
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
ret = max(ret, a[i][j]);
}
}
}
};
void go(Board c, int here){
if(here == 5){
c.get_max();
return;
}
for(int i=0; i<4; i++){
Board d = c;
d._move();
go(d, here+1);
c._rotate90();
}
return;
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> n;
Board c;
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
cin >> c.a[i][j];
}
}
go(c,0);
cout << ret << "\n";
return 0;
}
위의 코드는 강의내용과 같은 코드입니다.
강사님의 코드에서 move함수에 사용했을때 처음 c가 -1이면 if(d && a[i][j] == temp[i][c]) 이 가정문에서 temp[i][-1]이런경우가 되서 인덱스오류가 발생할거라 생각했는데 문제없이 넘어가는데 왜 그런건지 이해시켜주실 수 있을까요?
안녕하세요 준영님 ㅎㅎ
-1이 되는 경우는 없습니다.
d는 처음에 0입니다.
즉 이 if문은 d가 1일 때
이 라인이 체크가 됩니다. 0이라면 바로 else로 넘어가게 됩니다.
따라서 d는 처음에 0이므로 해당 부분에서 -1이 되는 경우는 없게 됩니다.
그리고
앞의 코드를 보시면 ++를 하면서 참조를 하기 때문에 초기에 temp[i][0]으로 참조되게 됩니다.
날카롭고 좋은 질문 감사합니다.
또 질문 있으시면 언제든지 질문 부탁드립니다.
좋은 수강평과 별점 5점은 제게 큰 힘이 됩니다. :)
감사합니다.
강사 큰돌 올림.
답글
양준영
2023.08.18답변 감사합니다.
제가 이해한 바로는 그러면 강의코드에서는 d를 먼저 검사하기때문에 c가 -1일때는 d가 0이기 때문에 a[i][j] == temp[i][c]라는 조건을 확인하지않고 다음 가정문으로 넘어간다고 이해되었습니다.
이렇게 이해하고 아래와 같이 코드를 변경해보았습니다.
Q1) 이 경우에도 예제가 문제없이 출력이 되는 것을 확인했는데, 잘못 이해를 한 걸까요?
Q2) 추가적으로 구조체안에 있는 temp배열들은 따로 초기화할필요가 없는지도 궁금합니다.
큰돌
2023.08.19안녕하세요 준영님 ㅎㅎ
Q1) 이 경우에도 예제가 문제없이 출력이 되는 것을 확인했는데, 잘못 이해를 한 걸까요?
>> 사실 C++은 -1 인덱스가 허용됩니다. 다만 UB가 뜰 수 있기 때문에 저렇게 로직을 구축하면 안됩니다.
이렇게 해도 0이 출력되는 것을 볼 수 있으실거에요
Q2) 추가적으로 구조체안에 있는 temp배열들은 따로 초기화할필요가 없는지도 궁금합니다.
temp배열은 매번 다음과 같이 어떠한 값으로 할당되기 때문에 굳이 처음에 초기화를 할 필요는 없습니다.