본문 바로가기
Algorithm

[백준] 16927

by ikii 2023. 8. 29.

기본 개념

배열을 겉 테두리부터 띠 형태로 해석

   열 증가
행         행
감         증
소         가
   열 감소

형태로 출발은 0에서 도착은 행과 열 중 더 작은 값의 /2에서 시작
과정 거치면서 출발은 +=1, 도착은 -= 1로 감소시키며 진행





코드 1, 실패, 230817

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;


public class Main {
    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        String[] str = br.readLine().split(" ");
        ArrayList<String[]> arr = new ArrayList<String[]>();
        ArrayList<LinkedList<String>> moveArr = new ArrayList<LinkedList<String>>();
        int startRow = 0;
        int endRow = Integer.parseInt(str[0])-1;
        int startColumn = 0;
        int endColumn = Integer.parseInt(str[1])-1;
        int min = Integer.parseInt(str[0]) > Integer.parseInt(str[1])? Integer.parseInt(str[1]) : Integer.parseInt(str[0]);

        for(int i = 0; i<Integer.parseInt(str[0]); i++){
            arr.add(br.readLine().split(" "));
        }


        for(int i = 0; i<min/2; i++){
            moveArr.add(new LinkedList<String>());
        }

        for(int i = 0; i<min/2; i++){
            int x = i;
            int y = i;

            while(true){
                moveArr.get(i).add(arr.get(x)[y]);
                if(x == startRow+1 && y == startColumn){
                    break;
                }
                if(x == i && y<endColumn){
                    y += 1;
                } else if (x < endRow && y == endColumn){
                    x += 1;
                } else if(x == endRow && y > startColumn){
                    y -= 1;
                } else if(x > startRow && y == startColumn){
                    x -= 1;
                }
            }

            for(int j = 0; j<Integer.parseInt(str[2]); j++){
                moveArr.get(i).add(moveArr.get(i).poll());
            }

            startRow += 1;
            endRow -= 1;
            startColumn += 1;
            endColumn -= 1;
        }

        startRow = 0;
        endRow = Integer.parseInt(str[0])-1;
        startColumn = 0;
        endColumn = Integer.parseInt(str[1])-1;
        for(int i = 0; i<min/2; i++){
            int x = i;
            int y = i;
            while(true){
                arr.get(x)[y] = moveArr.get(i).poll();
                if(x == startRow+1 && y == startColumn){
                    break;
                }
                if(x == i && y<endColumn){
                    y += 1;
                } else if (x < endRow && y == endColumn){
                    x += 1;
                } else if(x == endRow && y > startColumn){
                    y -= 1;
                } else if(x > startRow && y == startColumn){
                    x -= 1;
                }
            }
            startRow += 1;
            endRow -= 1;
            startColumn += 1;
            endColumn -= 1;
        }
        for(String[] i : arr){
            System.out.println(Arrays.toString(i));
        }
    }
}

문제

1% 시간 초과, 문제 성공 이후에 생각해도 출력에서 틀렸을 것

로직

테두리부터 띠 형태로 리스트에 값 저장
회전시켜야 하는 만큼 리스트 poll 하면서 뒤에 추가
다시 (0, 0) 좌표부터 리스트 값으로 교체






코드 2, 성공, 230817

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;


public class Main {
    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        String[] str = br.readLine().split(" ");
        ArrayList<String[]> arr = new ArrayList<String[]>();
        ArrayList<String[]> result = new ArrayList<String[]>();
        LinkedList<int[]> line;
        int startRow = 0;
        int endRow = Integer.parseInt(str[0])-1;
        int startColumn = 0;
        int endColumn = Integer.parseInt(str[1])-1;

        int min = Integer.parseInt(str[0]) > Integer.parseInt(str[1])? Integer.parseInt(str[1]) : Integer.parseInt(str[0]);

        for(int i = 0; i<Integer.parseInt(str[0]); i++){
            arr.add(br.readLine().split(" "));
            result.add(new String[Integer.parseInt(str[1])]);
        }

        for(int i = 0; i<min/2; i++){
            int x = i;
            int y = i;

            line = new LinkedList<int[]>();

            while(true){
                line.add(new int[]{x, y});
                if(x == startRow+1 && y == startColumn){
                    break;
                }
                if(x == i && y<endColumn){
                    y += 1;
                } else if (x < endRow && y == endColumn){
                    x += 1;
                } else if(x == endRow && y > startColumn){
                    y -= 1;
                } else if(x > startRow && y == startColumn){
                    x -= 1;
                }
            }

            for(int j = 0; j<line.size(); j++){
                int rotIndex = Integer.parseInt(str[2]) % line.size();
                if(j - rotIndex < 0){
                    rotIndex = line.size() - (rotIndex - j);
                    result.get(line.get(rotIndex)[0])[line.get(rotIndex)[1]] = arr.get(line.get(j)[0])[line.get(j)[1]];
                } else {
                    result.get(line.get(j-rotIndex)[0])[line.get(j-rotIndex)[1]] = arr.get(line.get(j)[0])[line.get(j)[1]];
                }
            }

            startRow += 1;
            endRow -= 1;
            startColumn += 1;
            endColumn -= 1;
        }

        for(String[] i : result){
            for(String j : i){
                System.out.print(j+" ");
            }
            System.out.println();
        }
    }
}

로직

for 행, 열 중 최소값/2

  • while로 테두리 돌면서 띠 형태로 회전하는 구간 저장
    • ex) (0, 0)부터 쭉 돌면서 좌표 리스트에 담고
  • for 띠 좌표 사이즈
    • 리스트 % 회전 사이즈 => 회전 결과 현재 좌표에서 몇번째 전인지
    • 회전 이후에 위치하는 좌표 확인
    • 현 좌표의 값 회전 후 좌표에 저장

      문제

      처음에 좌표를 구할 때 단순히 현재 인덱스 - 회전 거리가 0보다 크고 작고를 따졌는데 회전 거리가 띠 리스트를 몇번 회전하는지 모르기 때문에 미리 % 연산을 통해 최대 한번이라 가정시키고 현재 인덱스 - 연산 시에 0보다 작은지 큰지를 체크했다

출력 양식을 제대로 맞추지 않아 틀렸다 - 유의 필요

'Algorithm' 카테고리의 다른 글

[백준] 14891  (0) 2023.08.29
[백준] 5430  (0) 2023.08.29
[백준] 1790  (0) 2023.08.29
[백준] 22238  (0) 2023.08.29
[백준] 28291  (0) 2023.08.29

댓글