hyelie
hyelie
Hyeil Jeong
       
글쓰기    관리    수식입력
  • 전체보기 (495)
    • PS (283)
      • Algorithm (28)
      • PS Log (244)
      • Contest (6)
      • Tips (5)
    • Development (52)
      • Java (14)
      • Spring (23)
      • SQL (2)
      • Node.js (2)
      • Socket.io (3)
      • Study (4)
      • Utils (4)
    • DevOps (36)
      • Git (5)
      • Docker (4)
      • Kubernetes (2)
      • GCP (3)
      • Environment Set Up (8)
      • Tutorial (12)
      • Figma (2)
    • CS (74)
      • OOP (7)
      • OS (24)
      • DB (2)
      • Network (24)
      • Architecture (0)
      • Security (2)
      • Software Design (0)
      • Parallel Computing (15)
    • Project (15)
      • Project N2T (5)
      • Project ASG (0)
      • Project Meerkat (1)
      • Model Checking (7)
      • Ideas (2)
    • 내가 하고싶은 것! (34)
      • Plan (16)
      • Software Maestro (10)
      • 취준 (8)
hELLO · Designed By 정상우.
hyelie

hyelie

PS/PS Log

23.08.16. 풀었던 문제들 복기

9646. 다이어그램과 태블로, 2시간

 딱 보면 backtracking + purning으로 푸는 문제.

 일단 아래로 내릴 수 있으면 내리고, 너무 많이 내려간 경우 다음 col로 넘어가는 형식으로 구현했다.

 그러면 backtracking의 종료조건은 마지막 col을 탐색하고, 다음 칸을 탐색할 때 answer++를 해 주면 된다.

 다음으로, backtracking 과정은

  • 위/왼쪽에 있는 값을 보고 조건을 맞춘다.
  • 여기서 하나 purning을 하는데, 아래 칸으로 내릴 수 있으면 바로 내리고, 그렇지 않으면 바로 다음 col을 탐색한다.
    • 만약 이 과정을 recurse()에서 if문으로 걸면 call stack이 1번씩 더 쌓인다. worst case 모든 경우에 하나씩 더 쌓이게 되므로 이 과정을 여기로 뺀다.
  • 이것만으로 충분했다.
int k, N, num_col[8], board[8][8], answer;
// num_col[i] : i번째 row의 col 개수

// recurse(row, col) - row, col에서 backtrack
void recurse(int row, int col){
    // top-down recurse 종료조건
    if(row == 0 && num_col[row] <= col){
        answer++;
        return;
    }

    // 위/왼쪽 보고 가능한 숫자부터 recurse. 세로부터 채움.
    int s = 1;
    if(row > 0) s = max(s, board[row-1][col] + 1); // 위
    if(col > 0) s = max(s, board[row][col-1]); // 왼
    for(int i = s; i<=N; i++){
        board[row][col] = i;
        if(num_col[row+1] > col){ // 아래칸으로 내릴 수 있으면 내리고, 그렇지 않으면 바로 다음 col로 감.
            recurse(row+1, col);
        }
        else{
            recurse(0, col+1);
        }
    }
}

void solve(){
	while(1){
        cin>>k;
        if(cin.eof()) return;

        for(int i = 0; i<8; i++) num_col[i] = 0;
        for(int i = 0; i<8; i++){
            for(int j = 0; j<8; j++){
                board[i][j] = 0;
            }
        }

        for(int i = 0; i<k; i++) cin>>num_col[i];
        cin>>N;
        answer = 0;
        recurse(0, 0);
        cout<<answer<<"\n";
    }
}

//////////////////////

int main(void) {
	cin.tie(0);
	cout.tie(0);
	std::ios_base::sync_with_stdio(0);

	solve();

	return 0;
}

 

 

후기

 이런 purning 문제는 너무 빡세다.

 

 

 

 

저작자표시 (새창열림)

'PS > PS Log' 카테고리의 다른 글

23.08.21. 풀었던 문제들 복기  (0) 2023.08.21
23.08.17. 풀었던 문제들 복기  (0) 2023.08.17
23.08.15. 풀었던 문제들 복기  (0) 2023.08.15
23.08.11. 풀었던 문제들 복기  (0) 2023.08.11
23.08.10. 풀었던 문제들 복기  (0) 2023.08.11
    hyelie
    hyelie

    티스토리툴바