중복된 수가 있는 집합의 순열을 구할 때는 next_permutation의 비교문을 '='를 추가하기만 하면 된다.
이 문제는 크기가 k인 집합 중 6개를 뽑아서 순열을 사전식으로 출력하는 것이다.
사전식이기 때문에 새로운 배열 roto를 [0,0,0,0,0,0,1,1] 로 선언한다.
그런다음 이 배열을 처음 입력받은 크기가 k인 집합 arr과 비교하여 출력하는 것이다.
예를들어 roto[i]가 0이면 arr[i]를 선택하는 것이다.
그렇게 출력한 뒤 roto 배열의 다음 순열을 구하고 똑같은 과정을 거치면 중복된 수가 있는 집합의 순열을 구할 수 있다.
import java.util.Scanner; public class Main { public static boolean next_permutation(int[] arr){ int s=0; int e=arr.length; //arr[i-1] < arr[i]를 만족하는 가장 큰 i int i=e-1; for(; i>s; i--){ if(arr[i-1] >=arr[i]) continue; else break; } if(i==0) return false; //i<=j를 만족하고, A[j]>A[i-1]를 만족하는 가장 큰 j int j=e-1; for(; j>=i; j--){ if(arr[j]<=arr[i-1]) continue; else break; } //A[i-1], A[j] swap int tmp=arr[i-1]; arr[i-1]=arr[j]; arr[j]=tmp; //1234567 //i부터 끝까지 뒤집음 j=e-1; while(i<j){ int temp=arr[i]; arr[i]=arr[j]; arr[j]=temp; i++; j--; } return true; } public static void main(String[] args){ Scanner scan=new Scanner(System.in); boolean flag=false; while(true) { int k=scan.nextInt(); if(k==0) return; int[] arr=new int[k]; for(int i=0; i<k; i++) arr[i]=scan.nextInt(); if(flag) System.out.println(); int[] roto=new int[k]; for(int i=0; i<k; i++) { if(i<6) roto[i]=0; else roto[i]=1; } do { for(int i=0; i<k; i++) { if(roto[i]==0) System.out.print(arr[i]+" "); } System.out.println(); flag=true; }while(next_permutation(roto)); } } }
(2018-09-01 추가)
같은 문제를 백트래킹으로 구현해보았다.
두 코드의 속도는 놀랍게도 일치하는군, 개인적으로 아래 코드가 더 쉬운 것 같다.
import java.util.ArrayList; import java.util.Scanner; class Main{ //arr=주어진 배열, idx=현재 검사중인 인덱스, count=지금까지 채워진 인덱스, result=채우고있는 배열 public static void roto(int[] arr, int idx, int count, int[] result) { if(idx>=arr.length && count<6) { return; } if(count==6) {//6개 다 뽑음 for(int i=0; i<result.length; i++) System.out.print(result[i]+" "); System.out.println(); return; } //현재 인덱스를 포함하는 경우 result[count]=arr[idx]; roto(arr, idx+1, count+1, result); //현재 인덱스를 포함하지 않는 경우 result[count]=0; roto(arr,idx+1, count, result); } public static void main(String[] args){ Scanner scan=new Scanner(System.in); while(true) { int T=scan.nextInt(); if(T==0) return; int[] arr=new int[T]; for(int i=0; i<T; i++) arr[i]=scan.nextInt(); int[] result=new int[6]; roto(arr, 0,0, result); System.out.println(); } }
'이론 > 문제풀이' 카테고리의 다른 글
[백준알고리즘 - 9019] DSLR - java (BFS) (0) | 2018.08.26 |
---|---|
[백준알고리즘 -1697] 숨바꼭질 - Java(BFS) (0) | 2018.08.26 |
[백준-10992] 별 찍기 17 -Java (0) | 2018.08.16 |
[Codility] Lesson 6- GenomicRangeQuery (0) | 2018.08.12 |
[Codility] Lesson6- CountDiv (java) (0) | 2018.08.09 |