Java for test solution!

5 분 소요

안녕하세요 Legas 입니다. :)

지난번 포스팅에 이어서 N숫자가 입력되었을때 증가하는 숫자와 줄어드는 숫자문제를 반만 풀었었는데
오늘은 전부 완성시킨 코드와 왜 그렇게 풀게되었는지를 포스팅하도록 하겠습니다.

1. For문으로 숫자 둘러싸기

1부터 100사이의 N숫자가 주어졌을때 다음과 같이 나타낼 수 있게 코드를 만들기

Sample Input
2

Sample Output
4 4 4 4 4 4 4
4 3 3 3 3 3 4
4 3 2 2 2 3 4
4 3 2 1 2 3 4
4 3 3 3 3 3 4
4 4 4 4 4 4 4

Sample Input
7

Sample Output
7 7 7 7 7 7 7 7 7 7 7 7 7
7 6 6 6 6 6 6 6 6 6 6 6 7
7 6 5 5 5 5 5 5 5 5 5 6 7
7 6 5 4 4 4 4 4 4 4 5 6 7
7 6 5 4 3 3 3 3 3 4 5 6 7
7 6 5 4 3 2 2 2 3 4 5 6 7
7 6 5 4 3 2 1 2 3 4 5 6 7
7 6 5 4 3 2 2 2 3 4 5 6 7
7 6 5 4 3 3 3 3 3 4 5 6 7
7 6 5 4 4 4 4 4 4 4 5 6 7
7 6 5 5 5 5 5 5 5 5 5 6 7
7 6 6 6 6 6 6 6 6 6 6 6 7
7 7 7 7 7 7 7 7 7 7 7 7 7

1-1. 코드 설명

이전 포스팅
위의 링크에 이전 포스팅에 대한 정보가 있습니다.
이번 포스팅은 해당 문제를 거꾸로 뒤집어서 1부터 ~ N까지 증가하면서 둘러싸는 문제를 포스팅하도록 하겠습니다. 내용을 토대로 다시 한번 정리하자면

완성된 코드 펼치기
public static void main(String[] args) {
        Scanner star = new Scanner(System.in);
        int n = star.nextInt();
        int x = 1-n+n;
        int x1=x+1;
        int y = x;
        int z = 2*n-1;
        int z1=2*n-2;
        int c = 2*n-3;
        int v=-1;
        int a=4;
        int s=-2;
        int a1=-1;
        int s1=0;
        for(int i=0;i<z/2+1;i++){ // 열 만들기 + 증가했다가 감소하는 한줄을 +1로 한줄 더 만들기
            System.out.print(x+" "); // N의 숫자를 입력했을때 항상 가장 밖의 숫자는 고정시키기
            for(int j=0;j<c;j++){ // 
                if(i==n-1){ // 중간기점인 증가했다가 감소하는 한줄 코드 
                    System.out.print(x1+" ");
                    if(j>=c/2){ // N을 찍고나서 이후 작동
                        x1-=1; // N을 출력한 다음 -1씩 감소하도록 출력
                    }else{
                        x1+=1; // 처음 시작부터N까지 증가하면서 출력
                    }// 중간기점 한줄 코드 끝
                }else if(0<i&i<n-1){ // 첫번째 열인 0은 증가하는게 없고, n-1열은 중간기점이니 그 사이값을 출력하도록 설정
                    if(1<i&i<n-1){ // 2번째 열인 1 또한 처음 증가하는 숫자이후에 변동이 없으니 그 다음 값 설정
                        if(j>=z1){ 
                            System.out.print(s+" ");
                            s-=1;
                        }else if(j>=v){
                            System.out.print(y+" ");
                        }else{
                            System.out.print(a+" ");
                            a+=1;
                        }
                    }else{
                        System.out.print(y+" ");
                    }
                }else{
                    System.out.print(y+" ");
                }
            }
            System.out.println(x);
            y+=1;
            z1-=1; // 열이 증가할수록 감소되어야 하는 숫자의 행이 1개씩 많아지기 때문에 1씩 감소시켜 끝자리 행을 넓힘
            v+=1; // 1부터 가운데 계속 증가하는 행의 숫자를 감소시키기 위해 행을 줄임 
            if(i<3){
                a-=1; // 다음열에서 2부터 시작 할 수 있게 감소시키기
                s+=2; // 다음열에서 증가한 숫자로 출력할 수 있게 증가시키기
            }else{
                a-=a1;
                s+=s1;
            }
            a1+=1;
            s1+=1;
        }
        y-=2;
        int z2=n;
        int s2=n-2;
        int v2=n-3;
        int a2=2;
        int y2=n-1;
        int a3=n-3;
        int s3=n-4;
        for(int o=0;o<z/2;o++){
            System.out.print(x+" ");
            for(int k=0;k<c;k++){
                if(o<z/2+1){
                    if(k>=z2){
                        System.out.print(s2+" ");
                        s2-=1;
                    }else if(k>=v2){
                        System.out.print(y2+" ");
                    }else{
                        System.out.print(a2+" ");
                        a2+=1;
                    }
                }else{
                    System.out.print(y2+" ");
                }
            }
            System.out.println(x);
            y2-=1;
            z2+=1;
            v2-=1;
            s2+=s3;
            a2-=a3;
            a3-=1;
            s3-=1;


        }
    }

1-2. 코드 설명

첫번째 시도했던 코드는 for문을 너무 많이 써서 제한된 숫자만 완성할 수 있었습니다.
두번째 시도했던 코드는 if문을 너무 많이 써서 제한된 숫자까지만 완성할 수 있었습니다.

완성시키된 코드는 한번에 숫자를 만드려고 하지않고 2번에 나눠서 만들기로 했습니다.

  1. 알고리즘 찾기 N의 숫자가 주어질때 열과 행이 일정한 간격으로 증가하는것을 확인 할 수 있습니다.
    2의 숫자가 주어질때 열과 행은 3
    3의 숫자가 주어질때 열과 행은 5
    4의 숫자가 주어질때 열과 행은 7 …

  2. 열과 행 만들기
    위처럼 이런식으로 증가하기때문에 2*n-1이라는 공식을 대입하면 열과 행을 만들 수 있습니다.

    for(int i=0;i<z/2+1;i++)
    

    위에서 z = 2*n-1; 으로 반을 나눠서 했기때문에 z/2를 사용했고 중간에 N의 숫자까지 증가 > 감소를 하기위해 열을 한개 더 추가한것을 확인 할 수 있습니다.

다음 행을 만들기위해서 사용했던 for문

for(int j=0;j<c;j++)

위에서 c=2*n-3; 으로 열을 만들때 System.out.print(x+" ");로 시작과 끝을 사용했기 때문에 행에서 2개를 뺀 다음 시작하려고 for문을 만들었습니다.

  1. 행에서 점점 증가하는 숫자와 감소하는 숫자 만들기
                         if(j>=z1){ 
                             System.out.print(s+" ");
                             s-=1; // s가 출력되고 다음 출력시 -1을 감소하게 만듬
                         }else if(j>=v){ // 중간에 바뀌지 않는 숫자를 출력하기위해 만듬
                             System.out.print(y+" ");
                         }else{
                             System.out.print(a+" ");
                             a+=1; // a가 출력되고 다음출력시 +1을 증가하게 만듬 
                         }
    

숫자가 주어지면 0,1다음인 2열부터는 증가하는 숫자가 나오고 마지막에는 감소하는 숫자가 나오게 되기때문에
위처럼 셋팅을 해서 증가와 감소를 만들었습니다.

위의 행에서 증가와 감소만 주면 제대로 된 출력이 되지 않습니다. 예를 들어서
1 1 1 1 1 1 1
1 2 2 2 2 2 1
1 2 이부분에서 2가 출력되었지만 출력 후 a+=1;이 있기때문에 보이지 않지만 a의 저장값은 3으로 변경이 된 상태입니다.
이렇게되면 다음 열의 숫자에서는 a가 3로 저장되어있기 때문에 3부터 출력될 수 밖에 없습니다.

그래서 코드 마지막에 a-=1;를 사용하여 감소를 시켜서 다시 2부터 출력할 수 있게 만들었습니다.

반대로
1 1 1 1 1 1 1
1 2 2 2 2 2 1
1 2 3 3 3 2
이부분에서는 2가 출력 후 s-=1;이 있기 때문에 보이지 않지만 s의 저장값은 1로 변경이 된 상태입니다.
마찬가지로 이렇게되면 다음 열의 숫자에서는 s가 1로 저장되어있기 때문에 1부터 출력될 수 밖에 없습니다.
그래서 코드 마지막에 s+=2;를 사용하여 증가를 시켜서 다음 숫자가 출력되어야하는 3부터 감소하도록 만들었습니다.

  1. 출력하려고하는 행의 범위 설정
                         if(j>=z1){ //  int z1=2*n-2;
                             System.out.print(s+" ");
                             s-=1; 
                         }else if(j>=v){ // int v=-1;
                             System.out.print(y+" ");
                         }else{
                             System.out.print(a+" ");
                             a+=1; 
                         }
                         z1-=1; 
             v+=1; 
    

    if시작에 (j가 z1보다 크거나 같을때 ) 사용을 하면 N의 숫자가 4일 경우 z1 = 6이 됩니다.
    그럼 행이 5개인 열에서는 false가 될수밖에 없기 때문에 아래 for문이 1사이클이 돌고난 후 z1-=1;을 함으로서 5로 바꿔주게 되고 그다음 사이클이 돌고난 후 4로 변경되기때문에 행의 감소하는 숫자시작점을 점점 증가시킬 수 있습니다.

또한 else if의 (j가 v보다 크거나 같을경우) 사용을 하면 N의 숫자가 4일경우 j가 0일때 v= -1이고 다음사이클에서는v=0이 되기때문에 3번째 열부터는j의 범위가 줄어드는것을 확인 알 수 있습니다. 3번째 열에서 v=1이고j=0부터 시작함으로 0은 포함이 안되는 범위이니 else의 a가 출력되기 시작

반대로 중간기점을 다음으로 시작하는 숫자는 처음 만든 행과 반대로 만들어주면 문제를 완성시킬 수 있습니다.

짜잔 사진처럼 무작위 N의 숫자를 넣으면 문제를 완성 시키게 됩니다!.

댓글남기기