HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
🤎
프론트엔드 데브코스 5기 교육생
/
🙆
박병현팀
/
◾
멀쩡한 사각형
◾

멀쩡한 사각형

레벨
LV.2
날짜
Nov 3, 2023
링크
https://school.programmers.co.kr/learn/courses/30/lessons/62048

🔎 문제


school.programmers.co.kr
https://school.programmers.co.kr/learn/courses/30/lessons/62048
 

🧩 구현과정 및 코드

개인 토글 영역에 구현 과정과 코드를 자유롭게 작성해주시면 됩니다.

사용할 데이터 구조와 풀이 방향성
사용할 데이터 구조와 풀이 방향성
적용할 알고리즘 혹은 메서드
적용할 알고리즘 혹은 메서드

수영


구현

  • 기울기, 최대공약수 접근 방법 중 최대공약수 힌트를 참고했다.
    • w, h가 서로소(두 수 사이 공약수가 1 밖에 없는 관계)인 경우 w + h - 1
    • 서로소가 아닌 경우 w + h - 최대공약수
    • a % b === 0인 경우, b가 최대공약수

코드

function solution(w, h) { const gcd = (a, b) => { return a % b ? gcd(b, a % b) : b } const fullSquare = w * h const delSquare = w + h - gcd(w, h) return fullSquare - delSquare }

정은


구현

  1. (0,0) 과 (w,h)를 잇는 함수를 구함 : y = h/w*x 꼴
  1. x를 1씩 증가 시켰을 때, 위에서 구한 함수를 통해 스쳐지나가는 사각형 개수를 구함
    1. ⇒ 이전 y좌표가 소수일 때 해당 y를 내림하고, 현재 y가 소수일 때 해당 y를 올림해야 함.
      ex) x가 1씩 증가했고, 이전 y=0.5이고 현재 y=2.5이면
      y=0의 사각형, y=1의 사각형, y=2의 사각형을 모두 지나간 것이기 때문에 3개의 사각형, 즉 3(2.5를 반올림)-0(0.5를 반내림)개 . 지나간 것이다
      ⇒ 따라서,
      x=1일 때: (0,0)과 (1, h/w)를 스쳐 지나가는 사각형들 ⇒ 1 * (h/w반올림 - 0반내림)
      x=2일 때: (1, h/w)과 (2, h/w*2)를 스쳐 지나가는 사각형들 ⇒ 1 * (2반올림 - h/w*2반내림)
      …
  1. 지나간 사각형의 개수의 총합을 전체 사각형 크기에서 뺀 것이 정답

코드

function solution(w, h) { var notIncludedCount = 0; let prevY = 0 //이전 x에서 y좌표 for (let x=1; x<=w; x++) { //x는 1씩 증가, 즉 사각형의 크기를 구할 때 현재x-이전x=1이므로 y의 변화만 더해주면 됨 const y = h*x/w //현재 x에서 y좌표 notIncludedCount += Math.ceil(y)-Math.floor(prevY) //지금 y는 반올림, 예전 y는 반내림해서 스쳐 지나간 사각형의 크기를 구함 prevY = y } return w*h - notIncludedCout; }
  • 1차 시도) 포함되지 않는 사각형 크기를 구할 때, 스쳐 지나간 사각형의 크기를 반올림한게 아닌 사각형 크기 그 자체를 반올림 함
    • notIncludedCout += Math.ceil(y-prevY) ⇒ notIncludedCout += Math.ceil(y)-Math.floor(prevY) 로 변경
    • https://school.programmers.co.kr/questions/35128 테스트 케이스로 발견
  • 2차 시도) 테스트 6번 케이스에서 실패, 자바스크립트 소숫점의 나눗셈은 정확하지 않아서 생긴 문제
    • h/w*x ⇒ h*x/w 로 변경
    • https://school.programmers.co.kr/questions/35875 를 참고 함
 

더 간단한 코드

function solution(w,h){ const slope = h / w; let result = 0; for(let i = 1; i <= w; i++){ // 대각선 위에 있는 사각형들을 모두 더한다(조금이라도 걸리면 해당 사각형도 포함) result += Math.ceil(slope * i); } return ((h * w) - result) * 2; // (h * w) - result는 대각선 밑에 온전한 사각형들의 갯수, 위에도 똑같은 개수로 있으므로 *2 }
function solution(w,h){ const slope = h / w; let result = 0;
for(let i = 1; i <= w; i++){ result += Math.ceil(slope * i); } return ((h * w) - result) * 2;
}

종혁


구현

  • 그어지는 선이 일차함수
  • x좌표마다 위치하는 y의 위치가 현재 사용할 수 있는 정사각형의 수가 됨

코드

function solution(w, h) { let result = 0 for (let i = 0; i<w ; i++) { let 현재y위치 = (h*i)/w; result += Math.floor(현재y위치) } return result*2; } 0 0 1 1.5 2 3 3 4.5 4 6 5 7.5 6 9 7 10.5 8 12

재웅


구현

  1. 직방 활용
      • W, H 2차원 배열 전부 순회하면 시간 초과 날 듯
      • 기울기에 따라 한 열의 사용할 수 없는 사각형 갯수가 결정됨
  1. (해설)
    1. notion image

코드

function gcd(a, b) { while (b != 0) { let r = a % b; a = b; b = r; } return a; } function solution(w, h) { const total = w * h; const diagonal = w + h - gcd(w, h); return total - diagonal; }
 

✏️ 후기

문제를 풀고 느낀 점, 막혔던 부분 혹은 개선 사항 등을 자유롭게 작성해주시면 됩니다.

👧🏻
수영
  • w * (1~h)까지 패턴을 찾아보았는데 찾지 못했다. 수학 문제를 마주치면 당황스럽다.
👧🏻
정은
 
👦🏻
종혁
 
👦🏻
재웅
해설을 참고해도 이해가………..😵‍💫 수를 바꿀때마다 그래프를 그리기도 번거로워서 패턴을 발견하기 쉽지 않았다.