2147. Number of Ways to Divide a Long Corridor

  • 볡도에 의자 S 와 ν™”λΆ„ P 이 μžˆμ„ λ•Œ 벽을 μ„Έμ›Œμ„œ 각 곡간에 의자 2κ°œκ°€ ν¬ν•¨λ˜λ„λ‘ λ‚˜λˆ„λŠ” 경우의 수λ₯Ό κ΅¬ν•œλ‹€.
  • λ¨Όμ € μ–‘ 끝에 화뢄이 μžˆλ‹€λ©΄ μ œμ™Έμ‹œν‚¨λ‹€. μ–΄μ°¨ν”Ό 양끝에 μžˆλŠ” ν™”λΆ„ μ‚¬μ΄μ—λŠ” 벽을 μ„Έμš°κΈ° μ–΄λ €μš°λ―€λ‘œ 미리 μ œμ™Έμ‹œν‚€λ©΄ 문제λ₯Ό λ‹¨μˆœν™” ν•  수 μžˆλ‹€.
  • μ΄λ ‡κ²Œ μ–»μ–΄μ§„ μ‹œμž‘μ  pos κ³Ό 끝점 end을 κΈ°μ€€μœΌλ‘œ μ‹œμž‘μ μ„ μ›€μ§μ΄λ©΄μ„œ 칸막이λ₯Ό μ„Έμš°λŠ” 경우의 수λ₯Ό κ³„μ‚°ν•œλ‹€.
    • μΉΈλ§‰μ΄λŠ” μžλ¦¬κ°€ 2κ°œκ°€ λ˜λŠ” μ‹œμ λ§ˆλ‹€ μ„ΈμšΈ 수 μžˆλ‹€.
      • 단, μžλ¦¬κ°€ 2κ°œκ°€ λ˜μ§€ μ•Šμ•˜λŠ”λ° 화뢄이 λ“±μž₯ν•œλ‹€λ©΄ ν•΄λ‹Ή μœ„μΉ˜μ—λŠ” 칸막이λ₯Ό μ„ΈμšΈμˆ˜ μ—†μœΌλ―€λ‘œ λ¬΄μ‹œν•œλ‹€.
      • 만일 μžλ¦¬κ°€ 2κ°œκ°€ λ˜μ§€ λͺ»ν•œ μƒνƒœμ—μ„œ 볡도가 λλ‚œλ‹€λ©΄ 곡간을 λ‚˜λˆŒ 수 μ—†μœΌλ―€λ‘œ 경우의 μˆ˜λŠ” μ—†λŠ” 것이 λœλ‹€.
    • λ§Œμ•½ μžλ¦¬κ°€ 2κ°œκ°€ λ˜λŠ” μ‹œμ  λ°”λ‘œ 뒀에 화뢄이 μ—†λ‹€λ©΄ 칸막이λ₯Ό μ„ΈμšΈ 수 μžˆλ‹€. μ΄λ•Œ 경우의 μˆ˜λŠ” 1개 뿐이닀.
    • λ§Œμ•½μ— μžλ¦¬κ°€ 2κ°œκ°€ λ˜λŠ” μ‹œμ  이후에 화뢄이 μ‘΄μž¬ν•œλ‹€λ©΄ μ—°μ†λ˜λŠ” ν™”λΆ„μ˜ 개수 + 1 만큼 칸막이λ₯Ό μ„Έμš°λŠ” 경우의 μˆ˜κ°€ 생긴닀.
      • 예λ₯Ό λ“€μ–΄ SSPPSS 와 같은 경우 SS|PPSS SSP|PSS SSPP|SS 와 같이 μ„Έκ°€μ§€ 경우의 수둜 칸막이λ₯Ό μ„ΈμšΈ 수 μžˆλ‹€.
    • 전체 경우의 μˆ˜λŠ” 칸막이λ₯Ό μ„ΈμšΈ 수 μžˆλŠ” 지점 λ§ˆλ‹€μ˜ 경우의 수λ₯Ό κ³±ν•œ 것이 λœλ‹€.
class Solution { public: static constexpr int MOD = 1e9 + 7; int numberOfWays(string corridor) { int end = corridor.length() - 1; int pos = 0; int seats = 0; int plants = 0; long long result = 1; // skip first & last plants while (pos <= end) { if (corridor[pos] == 'P') ++pos; else break; } while (end >= pos) { if (corridor[end] == 'P') --end; else break; } while (pos <= end) { // count seats seats = 0; while (pos <= end && seats != 2) { if (corridor[pos] == 'S') ++seats; ++pos; } // cannot make 2 seats, so break the loop if (seats != 2) break; // count plants plants = 0; while (pos <= end) { if (corridor[pos] != 'P') break; ++pos; ++plants; } result = (result * (plants + 1)) % MOD; } // cannot make room with 2 seats return seats == 2? result : 0; } };