15652번: N과 M (4) (acmicpc.net)
15652번: N과 M (4)
한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다. 수열은 사전 순으로 증가하는 순서로 출력해
www.acmicpc.net
정답률 무려 79퍼.
바빠서 리뷰는 나중으로 미뤄뒀지만 어제 N과 M 1~3을 무난히 통과한 나는 자신감 있게 덤볐지만, 모종의 이유로 잠시 고생을 했다.
기본적으로 N과 M 1~3과 같으나, 정답을 추가할 때 "비내림차순" 조건에 들어맞는지 확인하는 구문을 넣어 주면 된다.
static void findAnswer(int[] arr,int depth,int r,int[] answer) throws IOException {
if(depth==r){
//정답 출력
for(int i=0;i<answer.length;i++){
bw.write(answer[i]+" ");
}
bw.newLine();
return;
}
for(int i=0;i<N;i++){
if(depth==0){
//맨 첫 단계에서는 그냥 넣으면 됨.
answer[depth] = arr[i];
findAnswer(arr,depth+1,r,answer);
}else{
//비내림차순인지 확인
if(answer[depth-1]<=arr[i]){
answer[depth] = arr[i];
findAnswer(arr,depth+1,r,answer);
}else{
break;
}
}
}
}
즉 depth가 0인 경우에는 어차피 비교 대상이 없으니 정답 배열(answer)에 무조건 수를 넣어 주고, 그 다음부터 depth==r 탈출조건을 만족할 때까지는 정답 배열에 이미 들어와 있는 마지막 수와 비교하면서 넣을지, 넘어갈지를 결정해주면 된다.
그런데 이 코드를 돌리면 가령 4,2의 input을 받은 경우, (1,1),(1,2),(1,3),(1,4) 까지만 출력하고 프로그램이 종료되어 버린다.
그 이유는 바로 쓸데없는 break문을 잘못 넣었기 때문이다.
if(answer[depth-1]<=arr[i]){
answer[depth] = arr[i];
findAnswer(arr,depth+1,r,answer);
}else{
break;
}
여기 else문에서 break구문을 만나면 저 if문을 빠져나가는 게 아니라 상위의 for문 자체를 빠져나가 버린다. 그래서 2부터 시작되는 수열들을 만들지 못하고 끝나 버린 것이다.
이런 문제는 사실 그냥 마우스만 대 봐도 바로바로 문제를 알 수 있는 건데, 당연히 어딘가에 내가 모르는 중대하고 심오한 오류가 있을 거라고 생각하며 다 뜯어 보느라 시간이 좀 걸렸다.
올바르게 수정한 코드는 아래와 같다. 올바르게 수정한 함수를 먼저 올리고, 전체 코드 올리고 마친다.
static void findAnswer(int[] arr,int depth,int r,int[] answer) throws IOException {
if(depth==r){
//정답 출력
for(int i=0;i<answer.length;i++){
bw.write(answer[i]+" ");
}
bw.newLine();
return;
}
for(int i=0;i<N;i++){
if(depth==0){
//맨 첫 단계에서는 그냥 넣으면 됨.
answer[depth] = arr[i];
findAnswer(arr,depth+1,r,answer);
}else{
//비내림차순인지 확인
if(answer[depth-1]<=arr[i]){
answer[depth] = arr[i];
findAnswer(arr,depth+1,r,answer);
}else{
break;
}
}
}
}
<전체 코드>
import java.io.*;
public class BOJ_15652_re {
static int N,M;
static int[] arr;
static int[] answer;
static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] NM = br.readLine().split(" ");
N = Integer.parseInt(NM[0]);
M = Integer.parseInt(NM[1]);
arr = new int[N];
for(int i=0;i<N;i++){
arr[i] = i+1;
}
answer = new int[M];
findAnswer(arr,0,M,answer);
bw.flush();
}
static void findAnswer(int[] arr,int depth,int r,int[] answer) throws IOException {
if(depth==r){
//정답 출력
for(int i=0;i<answer.length;i++){
bw.write(answer[i]+" ");
}
bw.newLine();
return;
}
for(int i=0;i<N;i++){
if(depth==0){
//맨 첫 단계에서는 그냥 넣으면 됨.
answer[depth] = arr[i];
findAnswer(arr,depth+1,r,answer);
}else{
//비내림차순인지 확인
if(answer[depth-1]<=arr[i]){
answer[depth] = arr[i];
findAnswer(arr,depth+1,r,answer);
}else{
break;
}
}
}
}
}
'프로그래밍 > 백준 복기' 카테고리의 다른 글
[BruteForce] BOJ1436: 영화감독 숌 (1) | 2023.11.15 |
---|---|
[BruteForce] 백준 1018 : 체스판 다시 칠하기 (0) | 2023.03.02 |
[BruteForce] 백준 1748: 수 이어 쓰기 1 (0) | 2022.10.04 |
[BruteForce] 백준 1107: 리모컨 (2) | 2022.10.03 |
[BruteForce] 백준 14500: 테트로미노 (0) | 2022.10.03 |