Java for test solution!
안녕하세요 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번에 나눠서 만들기로 했습니다.
-
알고리즘 찾기 N의 숫자가 주어질때 열과 행이 일정한 간격으로 증가하는것을 확인 할 수 있습니다.
2의 숫자가 주어질때 열과 행은 3
3의 숫자가 주어질때 열과 행은 5
4의 숫자가 주어질때 열과 행은 7 … -
열과 행 만들기
위처럼 이런식으로 증가하기때문에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문을 만들었습니다.
- 행에서 점점 증가하는 숫자와 감소하는 숫자 만들기
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부터 감소하도록 만들었습니다.
- 출력하려고하는 행의 범위 설정
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의 숫자를 넣으면 문제를 완성 시키게 됩니다!.
댓글남기기