[λ°±μ€€] #5525 IOIOIπŸ”˜

μ΅œμ •μœ€Β·2022λ…„ 5μ›” 4일
0
post-thumbnail

문제

λ¬Έμ œλŠ” κ°„λ‹¨ν•˜λ‹€. μš°μ„  I와 O둜 이루어진 λ¬Έμž₯κ³Ό N, M값이 주어진닀. μ΄λ•Œ, 주어진 λ¬Έμž₯μ—μ„œ PNP_N이 λͺ‡λ²ˆ λ‚˜μ˜€λŠ”μ§€ 좜λ ₯ν•˜λŠ” λ¬Έμ œμ΄λ‹€.

이 문제의 경우, μ œν•œ 쑰건에 따라 받을 수 μžˆλŠ” μ μˆ˜κ°€ λ‹¬λžλ‹€.

예제 μž…λ ₯


뢄석

문제 뢄석

μš°λ¦¬λŠ” IOIλΌλŠ” νŒ¨ν„΄μ„ μš°μ„  μ°Ύμ•„μ•Όν•œλ‹€. μ΄λ•Œ, IOIνŒ¨ν„΄μ˜ μ†μ—μ„œ Nλ§ŒνΌμ”© λͺ‡λ²ˆ λ°˜λ³΅ν•˜λŠ”μ§€λ₯Ό μ•Œμ•„μ•Όν•œλ‹€.
λ§Œμ•½ 주어진 λ¬Έμž₯이 IOIOIOI이고, N=2라면,

IOIOIOI
IOIOIOI

μ΄λ ‡κ²Œ 두 가지가 λ‚˜μ˜¨λ‹€.
IOIOIOI 의 λ‘λ²ˆμ§Έ I λΆ€ν„° μ„Έλ²ˆμ§Έ IκΉŒμ§€μ˜ ꡬ간은 μ€‘λ³΅λ˜μ–΄μ„œ μ„Έμ–΄μ§€λŠ” 것을 확인할 수 μžˆλ‹€.
이λ₯Ό 톡해, λ¬Έμžλ“€μ€ ν•œλ²ˆλ§Œ μ„Έμ•Ό ν•˜λŠ” 것이 μ•„λ‹ˆλΌ, νŒ¨ν„΄μ— ν¬ν•¨λ˜μ–΄μžˆκ³  νŒ¨ν„΄λ‚΄μ—μ„œμ˜ μœ„μΉ˜λ§Œ λ‹€λ₯΄λ‹€λ©΄ μ€‘λ³΅ν•΄μ„œ μ„Έμ–΄μ£Όμ–΄μ•Ό ν•œλ‹€λŠ” 것을 μ•Œ 수 μžˆλ‹€.

νŒ¨ν„΄μ˜ 반볡 횟수

λ˜ν•œ, IOIλΌλŠ” νŒ¨ν„΄μ΄ λͺ‡λ²ˆ λ°˜λ³΅λ˜λŠ”μ§€ μ•ˆλ‹€λ©΄ PNP_N이 λͺ‡ 번 λ‚˜μ˜€λŠ” 지도 μ•Œ 수 μžˆλ‹€.
μ˜ˆμ‹œλ‘œ λ“  λ¬Έμž₯의 κΈΈμ΄λŠ” 7이고, 이 λ¬Έμž₯μ—μ„œλŠ” IOIνŒ¨ν„΄λ§Œμ΄ 반볡되고 μžˆλ‹€. IOI νŒ¨ν„΄μ˜ 반볡 νšŸμˆ˜λŠ” O의 λ“±μž₯ νšŸμˆ˜μ™€ κ°™κ³ , O의 경우 λ¬Έμž₯길이의 μ•½ μ ˆλ°˜μ„ μ°¨μ§€ν•˜κ³  μžˆλ‹€. (O개수 = 3)

이것을 κ·œμΉ™μœΌλ‘œ λ§Œλ“€μ–΄λ³΄μž.
IOI νŒ¨ν„΄λ§Œμ΄ λ°˜λ³΅λ˜λŠ” 경우, λ¬Έμžμ—΄μ˜ 길이 / 2의 λͺ«μ€ IOI νŒ¨ν„΄μ˜ κ°œμˆ˜κ°€ λœλ‹€.

IOI νŒ¨ν„΄μ˜ 개수 =[ λ¬Έμžμ—΄μ˜ 길이 / 2 ]의 λͺ«

이제, IOI νŒ¨ν„΄μ˜ κ°œμˆ˜μ™€ PNP_N의 개수의 연관성을 μ°Ύμ•„λ³΄μž.

μ˜ˆμ‹œμ˜ IOI νŒ¨ν„΄ κ°œμˆ˜λŠ” 3이닀.
λ§Œμ•½ N=1이라면, PNP_N 은 3번 λ‚˜νƒ€λ‚œλ‹€.
λ§Œμ•½ N=2이라면, PNP_N 은 2번 λ‚˜νƒ€λ‚œλ‹€.
λ§Œμ•½ N=3이라면, PNP_N 은 1번 λ‚˜νƒ€λ‚œλ‹€.

PNP_N의 κ°œμˆ˜λŠ” IOI νŒ¨ν„΄ 개수 - (N-1)κ³Ό λ™μΌν•˜λ‹€λŠ” κ·œμΉ™μ„ 찾을 수 μžˆλ‹€.

PNP_N의 개수 = IOI νŒ¨ν„΄ 개수 - (N-1)


μ°Ύμ•„μ•Όν•  것

κ·Έλ ‡λ‹€λ©΄ μš°λ¦¬λŠ” 주어진 λ¬Έμž₯μ—μ„œ 무엇을 μ°Ύμ•„μ•Όν• κΉŒ?
μš°μ„  IOIκ°€ μ—°μ†λœ ꡬ간듀을 μ•Œμ•„μ•Όν•  것이닀.
이 ꡬ간을 μ•ˆλ‹€λ©΄, κ΅¬κ°„λ§ˆλ‹€ μ•žμ—μ„œ μ°Ύμ•„λ‚Έ κ·œμΉ™μ„ μ μš©ν•˜μ—¬, 총 PNP_N의 개수λ₯Ό μ•Œμ•„λ‚Ό 수 μžˆμ„ 것이닀.


κ΅¬ν˜„

IOIκ°€ μ—°μ†λœ ꡬ간을 μ°ΎκΈ° μœ„ν•΄μ„œ, μŠ€νƒμ„ μ‚¬μš©ν•  것이닀.
μš°λ¦¬λŠ” 주어진 λ¬Έμž₯을 ν•œ λ¬Έμžμ”© μ½μœΌλ©΄μ„œ, IOI의 νŒ¨ν„΄κ³Ό μΌμΉ˜ν•˜λŠ”μ§€ μ•„λ‹Œμ§€λ₯Ό νŒλ‹¨ν•΄μ•Ό ν•œλ‹€. λ‚΄κ°€ ν˜„μž¬ 읽고 μžˆλŠ” λ¬Έμžκ°€ νŒ¨ν„΄μ— μ ν•©ν•œμ§€λ₯Ό μ•ŒκΈ° μœ„ν•΄μ„œλŠ” 이전 λ¬Έμžκ°€ 무엇인지 μ•Œμ•„μ•Όν•œλ‹€.

λ”°λΌμ„œ, 문자λ₯Ό 읽은 ν›„, μŠ€νƒμ˜ top을 μ‘°νšŒν•˜μ—¬ ν˜„μž¬ 문자λ₯Ό μŠ€νƒμ— λ„£μ—ˆμ„ λ•Œ IOI νŒ¨ν„΄μ„ μœ μ§€ν•  수 μžˆλŠ”μ§€λ₯Ό 확인할 것이닀.

λ§Œμ•½ IOI νŒ¨ν„΄μ„ μœ μ§€ν•  수 μ—†λŠ” 문자라면, 더이상 IOI νŒ¨ν„΄μ˜ μ—°μ†λœ ꡬ간이 μ•„λ‹ˆλΌλŠ” μ˜λ―Έμ΄λ―€λ‘œ, μŠ€νƒμ— μžˆλŠ” μ—°μ†λœ IOI νŒ¨ν„΄λ“€μ—μ„œ PNP_N의 개수λ₯Ό κ΅¬ν•˜κ³ , μŠ€νƒμ„ λΉ„μšΈ 것이닀.

문자λ₯Ό μŠ€νƒμ— 넣을지 말지 κ²°μ •ν•˜λŠ” κ·œμΉ™μ€ μ•„λž˜μ™€ 같이 μ„€μ •ν•˜μ˜€λ‹€.

  • ν˜„μž¬ 읽은 λ¬Έμžκ°€ O인 경우
    - μŠ€νƒμ˜ top이 I➑ κ·œμΉ™ 만쑱 β­•: μŠ€νƒμ— push
    - μŠ€νƒμ΄ λΉ„μ–΄μžˆμŒ ➑ κ·œμΉ™ 뢈만쑱 ❌ : κ·Έλƒ₯ 버리기
    - μŠ€νƒμ˜ top이 O➑ κ·œμΉ™ 뢈만쑱 ❌ : μŠ€νƒμ— μžˆλŠ” O 제거 ν›„, PNP_N 개수 계산 & μŠ€νƒ λΉ„μš°κΈ°

  • ν˜„μž¬ 읽은 λ¬Έμžκ°€ I인 경우
    - μŠ€νƒμ΄ λΉ„μ–΄μžˆμŒ ➑ κ·œμΉ™ 만쑱 β­•: μŠ€νƒμ— push
    - μŠ€νƒμ˜ top이 O➑ κ·œμΉ™ 만쑱 β­•: μŠ€νƒμ— push
    - μŠ€νƒμ˜ top이 I ➑ κ·œμΉ™ 뢈만쑱 ❌ : PNP_N 개수 계산 & μŠ€νƒ λΉ„μš°κΈ°

μ½”λ“œ

μœ„μ˜ κ΅¬ν˜„ 사항을 μ•„λž˜μ™€ 같이 μž‘μ„±ν•˜μ˜€λ‹€.

#include <iostream>
#include <stack>

using namespace std;

int cnt=0;
int N,M;
int i;
char c;
stack<char> s;
void count();
int main()
{
    cin >> N;
    cin >> M;
    
    for(i=0;i<M;i++){
       cin >> c;
       
       if(c=='O'){ // ν˜„μž¬ λ¬Έμžκ°€ O인 경우 
            if (s.empty()) // μŠ€νƒμ΄ 빈 경우 
                continue;
            else if(s.top() == 'I') // μŠ€νƒμ˜ top이 I인 경우
               s.push(c);
            else{ // μŠ€νƒμ˜ top이 O인 경우
                s.pop();
                count();
            }
           
       }else{ //  ν˜„μž¬ λ¬Έμžκ°€ I 인 경우 
            if(!s.empty() && s.top()=='I' )  // μŠ€νƒμ΄ λΉ„μ–΄μžˆκ±°λ‚˜ top이 I인 경우 
                count();
           
            s.push(c);
       }
       
    }
    
    if(!s.empty()){
        if(s.top()=='I')
        count();
        else{
            s.pop();
            count();
        }   
    }
    cout<<cnt;

    return 0;
}

void count(){
    int pNum  = s.size()/2-(N-1) ;
    if(pNum>0)
        cnt+=pNum;
    s = stack<char>();
}

μ‹€μˆ˜ν–ˆλ˜ λΆ€λΆ„

μœ„μ˜ μ½”λ“œλŠ” μˆ˜μ • ν›„μ˜ μ½”λ“œμ΄λ‹€.
μˆ˜μ • μ „ μ½”λ“œμ—μ„œ κ°„κ³Όν–ˆλ˜ 뢀뢄듀을 짚고 λ„˜μ–΄κ°€κ³ μž ν•œλ‹€.

1. count ν•¨μˆ˜

μœ„μ—μ„œ 문제λ₯Ό 뢄석할 λ•Œ, PNP_N을 κ³„μ‚°ν•˜λŠ” 식을 μž‘μ„±ν–ˆμ—ˆλ‹€.

PNP_N의 개수 = IOI νŒ¨ν„΄ 개수 - (N-1)

이 λ‚΄μš©μ„ countν•¨μˆ˜λ‘œ κ΅¬ν˜„ν•˜μ˜€λ‹€.

void count(){
    int pNum  = s.size()/2-(N-1) ;
    cnt+=pNum;
    s = stack<char>();
}

그런데 이 μˆ˜μ‹μ—μ„œ μ£Όμ˜ν•΄μ•Ό ν•  점은, IOI νŒ¨ν„΄ κ°œμˆ˜κ°€ N-1보닀 μž‘μ„ μˆ˜λ„ μžˆλ‹€λŠ” 것이닀.
λ”°λΌμ„œ, λ³„λ„μ˜ 쑰건없이 μž‘μ„±ν•˜λ©΄ PNP_N의 κ°œμˆ˜κ°€ μŒμˆ˜κ°€ λ‚˜μ˜€κ²Œ 되고, λ‹Ήμ—°νžˆ ν‹€λ¦° κ²°κ³Όλ₯Ό μ–»κ²Œ λœλ‹€.
λ”°λΌμ„œ, PNP_Nκ°€ μŒμˆ˜κ°€ 될 경우 전체 결과에 반영이 μ•ˆλ˜λ„λ‘ μˆ˜μ •ν•˜μ˜€λ‹€.

void count(){
    int pNum  = s.size()/2-(N-1) ;
    if(pNum>0)
        cnt+=pNum;
    s = stack<char>();
}

이처럼 μ–΄λ– ν•œ κ·œμΉ™μ„ μˆ˜μ‹μœΌλ‘œ μž‘μ„±ν•  λ•ŒλŠ”, κ·Έ 식이 μ˜ˆμ™Έμ μΈ κ²°κ³Όλ₯Ό λ°°μΆœν•˜μ§€λŠ” μ•ŠλŠ”μ§€ κ³ λ €λ₯Ό 꼼꼼히 해보아야 ν•œλ‹€.

2. λŸ°νƒ€μž„ μ—λŸ¬

μ½”λ“œ μ‹€ν–‰ 쀑 무언가 였λ₯˜κ°€ λ°œμƒν•œ 상황이닀.
디버깅을 톡해, μŠ€νƒμ˜ μ ‘κ·Ό 쀑 잘λͺ»λœ 뢀뢄이 μžˆλ‹€λŠ” 사싀을 ν™•μΈν–ˆλ‹€.
λ‚˜μ˜ λ‘œμ§μ—λŠ” μŠ€νƒμ˜ top을 μ‘°νšŒν•˜λŠ” 뢀뢄이 μ‘΄μž¬ν•œλ‹€.
κ·ΈλŸ¬λ‚˜ μŠ€νƒμ΄ λΉ„μ–΄μžˆλŠ” 경우, top을 μ‘°νšŒν•˜κ²Œ 되면 였λ₯˜κ°€ λ°œμƒν•œλ‹€.

if (s.empty()) // μŠ€νƒμ΄ 빈 경우 
	continue;
else if(s.top() == 'I') // μŠ€νƒμ˜ top이 I인 경우
	s.push(c);
else // μŠ€νƒμ˜ top이 O인 경우
{ 
	s.pop();
	count();
}

λ”°λΌμ„œ μœ„μ™€ 같이 emptyμ—¬λΆ€λ₯Ό νŒλ‹¨ν•˜λŠ” 쑰건을 λ¨Όμ € λ°°μΉ˜ν•΄μ£Όμ–΄μ•Ό 였λ₯˜κ°€ λ°œμƒν•˜μ§€ μ•Šκ²Œ λœλ‹€.

λŠλ‚€ 점

κ·œμΉ™μ„ μ°ΎλŠ” λ¬Έμ œλŠ” μ˜ˆμ™Έμ‚¬ν•­μ„ μ™„λ²½ν•˜κ²Œ μ²˜λ¦¬ν•˜λŠ” 방법을 잘 μƒκ°ν•˜λ©΄ ν•œλ°©μ— ν’€λ¦¬μ§€λ§Œ, μ—¬κΈ°μ €κΈ° 빈 ꡬ석듀이 μ‘΄μž¬ν•˜λ©΄ ν•œμ—†μ΄ ν‹€λ¦¬λŠ” 문제인 것 κ°™λ‹€.
🌟 λ‚΄κ°€ μƒκ°ν•˜λŠ” 것보닀 더 κΌΌκΌΌν•˜κ²Œ μƒκ°ν•˜κΈ°!

profile
맀일 λΏŒλ“―ν•˜κΈ°πŸ¬πŸ­πŸ‘πŸ«

0개의 λŒ“κΈ€