본문 바로가기

백준

5430번:AC(Java)

 int 배열과 시작, 끝, 현재 index를 사용해 풀었다. R을 할 때마다 순서를 바꾸는 것은 시간이 너무 오래 걸릴 것이라 판단했다. 배열을 그대로 두고 연산 실행 시 시작, 끝, 현재 index 연산만 하면 시간복잡도를 줄일 수 있을 거라고 생각했다.

 메모리는 D를 할 때마다 조금씩 낭비될 수는 있지만 시간을 줄이는 것이 더 이득이라 생각한 결과이다.

 

 

변수들을 다음과 같이 선언했다.

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int[] list;//배열
int n = Integer.parseInt(br.readLine());//반복 횟수
String[] order;//명령
int size;//배열 크기
int start;//끝 위치
int end;//시작 위치
int now;//현재 위치
String arr;//문자열로 입력받을 배열
StringBuilder result;//결과

 

입력을 받은 후 입력받은 문자열을 substring과 split을 통해 배열에 넣어주고 명령 분석을 시작했다.

 
public static void input(int[] list, String nums)
{
    //문자열의 길이가 2라면 빈 배열이므로 return
    if(nums.length() == 2)
    {
        return;
    }
    String[] nlist = nums.substring(1, nums.length()-1).split(",");

    for(int i = 0; i<nlist.length; i++)
    {
        list[i] = (Integer.parseInt(nlist[i]));
    }
}

 

result = new StringBuilder();
order = br.readLine().split("");//명령 입력
size = Integer.parseInt(br.readLine());//배열 크기 입력
list = new int[size];//배열 초기화
arr = br.readLine();//문자열로 배열 입력
input(list, arr);//입력받은 문자열을 배열로 삽입
start = 0;//시작 위치 초기화
now = start;//현재 위치를 시작 위치로
end = size-1;//끝 위치를 배열 크기 -1 로(index 이므로)

 

 

 

이렇게 하면 우선 그림과 같이 설정된다.

 

 

이제 명령에 따라 index들을 연산하면 된다.

1. 명령이 R 인 경우

 - now가 start라면 now를 end로 옮긴다.

 - now가 end라면 now를 start로 옮긴다.

 

2. 명령이 D 인 경우

 - now가 start라면 now++, start++를 통해 한 칸 앞으로 이동한다. (삭제와 같은 효과이지만 실제로 배열을 건드리지는 않는다.)

 - now가 end라면 now--, end--를 통해 한 칸 뒤로 이동한다. (마찬가지로 배열을 건드리지는 않는다.)

 

이걸 이해하기 쉽게 그림으로 표현해 보겠다.

 

 

0. 입력

 입력을 받은 후의 상태이다.

 

 

1. R

 now가 start이므로 now가 end로 이동한다

 

 

2. D

now가 end 이므로 now--, end--를 통해 배열을 건드리지 않으면서 index만 이동한다

 

 

 

3. R

 now가 end 이므로 now가 start로 이동한다.

 

 

 

4. D

 now가 start 이므로 now++, start++ 로 배열을 건드리지 않으면서 index만 이동한다.

 

 

 

이러면 연산은 끝났다. 이제 출력만 하면 된다.

출력은 간단하다. 세 가지 조건을 따지면 된다.

 

1. start > end + 1인 경우

 - 배열이 비어있는 상태에선 start = end + 1이다(start == end이면 원소가 한 개 있는 경우이므로)

 - 따라서 start > end + 1이면 배열이 비어있는 상태에서 D 명령을 했다는 것이므로 error를 출력하면 된다.

 

2. now == start 인 경우

 - 배열의 현재 상태가 정방향이라는 것을 의미한다. 

 - 따라서 start부터 end까지 출력하면 된다.

 

3. now == end 인 경우

 - 배열의 현재 상태가 역방향이라는 것을 의미한다.

 - 따라서 end부터 start까지 역방향으로 출력하면 된다.

 

 

5. 출력

 

 

 

 

 

여태까지 한 과정을 코드로 나타내면 이렇다.

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int[] list;//배열
int n = Integer.parseInt(br.readLine());//반복 횟수
String[] order;//명령
int size;//배열 크기
int start;//끝 위치
int end;//시작 위치
int now;//현재 위치
String arr;//문자열로 입력받을 배열
StringBuilder result;//결과

for(int i = 0; i<n; i++)
{
    result = new StringBuilder();
    order = br.readLine().split("");//명령 입력
    size = Integer.parseInt(br.readLine());//배열 크기 입력
    list = new int[size];//배열 초기화
    arr = br.readLine();//문자열로 배열 입력
    input(list, arr);//입력받은 문자열을 배열로 삽입
    start = 0;//시작 위치 초기화
    now = start;//현재 위치를 시작 위치로
    end = size-1;//끝 위치를 배열 크기 -1 로(index 이므로)


    //명령을 하나씩 수행
    for(String o : order)
    {
        //R(reverse)이면 현재 위치를 바꾼다
        if(o.equals("R"))
        {
            now = now == start ? end : start;
        }
        //D(delete)이면 현재 위치와 시작 혹은 끝 위치를 +1 하거나 -1 한다
        else
        {
            if(now == start)//현재 위치가 시작 위치이면 +1
            {
                now++;
                start++;
            }
            else//현재 위치가 끝 위치이면 -1
            {
                now--;
                end--;
            }
        }
    }

    //만약 시작 위치가 끝 위치 +1 보다 크다면 배열이 비어있는 상태에서 Delete를 한 것이므로 error
    if(start > end+1)
    {
        result.append("error");
    }
    //현재 위치가 시작 위치라면 시작 위치부터 끝 위치까지 출력
    else if(now == start)
    {
        result.append("[");
        for(int j = now; j<=end; j++)
        {
            result.append(list[j]+",");
        }
        if(result.length() == 1)
        {
            result.append("]");
        }
        else
        {
            result.replace(result.length()-1, result.length(), "]");
        }
    }
    //현재 위치가 끝 위치라면 끝 위치부터 시작 위치까지 출력
    else if(now == end)
    {
        result.append("[");
        for(int j = now; j>=start; j--)
        {
            result.append(list[j]+",");
        }
        if(result.length() == 1)
        {
            result.append("]");
        }
        else
        {
            result.replace(result.length()-1, result.length(), "]");
        }
    }
    System.out.println(result);
}

 

 

 

 

 

 

 

결과 코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class Main
{
    //배열에 문자열을 넣는 함수
    public static void input(int[] list, String nums)
    {
        //문자열의 길이가 2라면 빈 배열이므로 return
        if(nums.length() == 2)
        {
            return;
        }
        String[] nlist = nums.substring(1, nums.length()-1).split(",");

        for(int i = 0; i<nlist.length; i++)
        {
            list[i] = (Integer.parseInt(nlist[i]));
        }
    }
    public static void main(String[] args) throws IOException
    {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int[] list;//배열
        int n = Integer.parseInt(br.readLine());//반복 횟수
        String[] order;//명령
        int size;//배열 크기
        int start;//끝 위치
        int end;//시작 위치
        int now;//현재 위치
        String arr;//문자열로 입력받을 배열
        StringBuilder result;//결과

        for(int i = 0; i<n; i++)
        {
            result = new StringBuilder();
            order = br.readLine().split("");//명령 입력
            size = Integer.parseInt(br.readLine());//배열 크기 입력
            list = new int[size];//배열 초기화
            arr = br.readLine();//문자열로 배열 입력
            input(list, arr);//입력받은 문자열을 배열로 삽입
            start = 0;//시작 위치 초기화
            now = start;//현재 위치를 시작 위치로
            end = size-1;//끝 위치를 배열 크기 -1 로(index 이므로)


            //명령을 하나씩 수행
            for(String o : order)
            {
                //R(reverse)이면 현재 위치를 바꾼다
                if(o.equals("R"))
                {
                    now = now == start ? end : start;
                }
                //D(delete)이면 현재 위치와 시작 혹은 끝 위치를 +1 하거나 -1 한다
                else
                {
                    if(now == start)//현재 위치가 시작 위치이면 +1
                    {
                        now++;
                        start++;
                    }
                    else//현재 위치가 끝 위치이면 -1
                    {
                        now--;
                        end--;
                    }
                }
            }

            //만약 시작 위치가 끝 위치 +1 보다 크다면 배열이 비어있는 상태에서 Delete를 한 것이므로 error
            if(start > end+1)
            {
                result.append("error");
            }
            //현재 위치가 시작 위치라면 시작 위치부터 끝 위치까지 출력
            else if(now == start)
            {
                result.append("[");
                for(int j = now; j<=end; j++)
                {
                    result.append(list[j]+",");
                }
                if(result.length() == 1)
                {
                    result.append("]");
                }
                else
                {
                    result.replace(result.length()-1, result.length(), "]");
                }
            }
            //현재 위치가 끝 위치라면 끝 위치부터 시작 위치까지 출력
            else if(now == end)
            {
                result.append("[");
                for(int j = now; j>=start; j--)
                {
                    result.append(list[j]+",");
                }
                if(result.length() == 1)
                {
                    result.append("]");
                }
                else
                {
                    result.replace(result.length()-1, result.length(), "]");
                }
            }
            System.out.println(result);
        }
    }
}

'백준' 카테고리의 다른 글

9935번:문자열 폭발(Java)  (0) 2023.02.24
5052번:전화번호 목록(Java)  (1) 2023.02.24
1927번:최소 힙(Java)  (0) 2023.02.20
11286번:절댓값 힙(Java)  (0) 2023.02.20
1302번: 베스트셀러(Java)  (0) 2023.02.19