이에 해당하는 문제들은 10039번, 5543번, 10817번, 2523번, 2446번, 10996번으로 총 6문제이다. 이 중 2446번과 10996번이 생각을 많이 요구하는 문제로 두 문제 다 이중포문을 요구하는 문제였다.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.StringTokenizer;
public class Main {
public static void main(String args[]) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer tokenizer = null;
int N = 0;
try {
N = Integer.parseInt(br.readLine());
for(int i = N; i > 1; i --)
{
for(int k = 0 ; k < N-i ; k++)
{
bw.write(" ");
}
for(int j = 2*i-1; j>0; j--)
{
bw.write("*");
}
bw.write("\n");
}
for(int i = 1 ; i < N+1; i++)
{
for(int k = N ; k > i; k--)
{
bw.write(" ");
}
for(int j = 0; j < 2*i-1 ; j++)
{
bw.write("*");
}
bw.write("\n");
}
br.close();
bw.flush();
bw.close();
} catch (Exception e) {
}
}
}
위에 보다시피 코드가 깨끗하지도 않고 너저분하고 내가 코딩을 잘 하는것도 아니지만 그래도 이중포문을 구현할 때의 방법에 있어서 개인적인 생각을 정리하자면, 이중포문에서 바깥포문은 행 반복에 대한 구성, 안의 포문은 열 반복에 대한 구성이라고 생각하면 이해가 쉽다.
그러면 대충 어떻게 구성을 해 나갈지 감이 조금 올 수 있다. 우선 바깥포문을 구성한 뒤에는, 안 포문에 대해서 생각할 때 첫번째 경우와 마지막 경우를 생각하면 쉽다. 이중포문의 제일 첫 시작의 경우와 제일 끝 경우를 말하는 것이다.
*
**
***
입력이 3일때 이런 별찍기가 있을 때, 규칙이 점점 늘어나는 별이고 별다른 그 이상의 규칙은 없으므로 바깥 포문은 전체 N(여기서는 3)회, 안쪽 포문은 공백포문 하나, 그리고 별 포문 하나면 되겠다.
for(int i = 1 ; i < N+1; i++)
{
for(int k = N ; k > i; k--)
{
bw.write(" ");
}
for(int j = 0; j < 2*i-1 ; j++)
{
bw.write("*");
}
bw.write("\n");
}
공백이 어떻게 출력되어야 하냐를 생각해 보자면, 제일 첫번째에는 N-1번 출력되어야 하고, 제일 마지막에는 출력이 되면 안된다는 것을 생각하고, 바깥 포문의 변수 i의 처음과 끝( 첫번째 경우는 i = 1, 마지막 경우는 i = N)을 생각하여 안쪽 포문의 처음과 마지막 경우를 잡아줄 수 있을 것이다. 그리고 이에 더해 i 가 어떻게 변하느냐 (위 코드의 경우, 점점 증가하는 ++ )를 생각하며 안쪽 포문의 비교문이나 증감문을 잡아줄 수 있다.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.StringTokenizer;
public class Main {
public static void main(String args[]) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer tokenizer = null;
int N = 0;
try {
N = Integer.parseInt(br.readLine());
if(N==1)
bw.write("*");
else {
for (int i = 0; i < N; i++) {
for (int j = 1; j < N + 1; j++) {
if (j % 2 == 1)
bw.write("*");
else
bw.write(" ");
}
bw.write("\n");
for (int j = 1; j < N + 1; j++) {
if (j % 2 == 1)
bw.write(" ");
else
bw.write("*");
}
bw.write("\n");
}
}
br.close();
bw.flush();
bw.close();
} catch (Exception e) {
}
}
}
해당 문제의 규칙성을 생각해 바깥 포문을 먼저 잡았다. 1입력일때 1줄, 2입력일때 4줄, 3입력일때 6줄, 4입력일때 8줄인 상황을 보아하니
전체 포문의 경우를 N*2로 잡아도 되겠지만, 나는 전체 경우를 N으로 잡았다. 왜냐고? 나는 안쪽 포문의 역할을 한줄로 둔 게 아니라, 두 줄로 두었기 때문이다. 그림의 규칙성을 보아하니 두 줄 단위로 묶어서 반복됨을 볼 수 있다. 따라서 두 줄 단위를 안쪽 포문으로 두겠다고 생각했고, 바깥 포문은 따라서 N번으로 잡게 된 것이다.
결국 이중포문은 내가 구현하는 것. 바깥 포문이 행이고 안 포문이 열이라고 해서, 16줄이니 바깥포문은 16번 반복되어야 할 필요는 없다.