티스토리 뷰
#include <stdio.h>
#include <stdlib.h>
long int n, k;
int cnt = 0;
void loop(long int max, long int num, int a[], int b[])
{
if(num == 0) {
for(int i = 0; i<cnt; i++) printf("%d ", b[i]);
for(int i = 0; i<n; i++)
if(a[i] > 0) printf("%d ", a[i]);
exit(0);
}
int j = 0;
for(j = max; j>0; j--)
{
long int tmp = num-j;
if(tmp >=0) {
b[cnt++] = j+1;
a[j] = 0;
loop(max-1, tmp, a, b);
}
}
if(num > 0 && j==0) {
printf("-1");
exit(0);
}
}
int main(void)
{
scanf("%ld %ld", &n, &k);
int a[n];
int b[n];
for(int i = 0; i<n; i++) a[i] = i+1;
loop(n-1, k, a, b);
}
https://www.acmicpc.net/problem/17505
17505번: 링고와 순열
링고는 1이상 N이하의 정수가 한 번씩 모두 등장하는 길이가 N인 순열 [p1, p2, ..., pN]을 좋아합니다. 그 중에서 반전의 개수가 K인 순열을 제일 좋아합니다. 순열에서 반전이란 i < j 이면서 pi > pj 를
www.acmicpc.net
풀이
ex) N = 5일 때 가능한 반전의 개수 0 ~ 10
1 2 3 4 5 = 0개
5 1 2 3 4 = 4개
4 1 2 3 5 = 3개
3 1 2 4 5 = 2개
2 1 3 4 5 = 1개 이므로,
0~10까지의 반전을 만들 수 있다. 그 이상은 불가능 하다.
1) 배열 생성
a[n] : 1~n까지를 담는 배열 생성
b[n] : 이동 시킨 수를 담는 배열
2) 재귀 함수, 특정 순열을 만들 수 있는 가?
(반전의 개수 - 숫자를 하나 옮겼을 때 만들어지는 반전의 개수) > 0 을 반복해서,
반전의 개수가 0이 되면 특정 순열을 만들 수 있음을 의미다.
여기서 순열에 같은수는 존재 하지 않으므로, 특정 숫자를 한 번 옮겼을 때
그 수를 b[]에 저장한 후, 더 이상 옮기지 못하게 만든다 (a[]에 있는 그 수를 0으로 만든다)
3) 처음 입력 받았던 반전의 개수가 0 이되면, 특정 순열을 출력 (b[] 출력 후 a[]출력)
(단 b[]에서 출력했던 것은 a[]에서 출력해서는 안됨)
역으로 처음 입력 받았던 반전의 개수가 0이 될 수 없다면 -1을 출력
'c언어 > BAEKJOON' 카테고리의 다른 글
c언어 5014번 스타트링크 (백준) (0) | 2022.08.23 |
---|---|
c언어 14852번 타일 채우기 (백준) (0) | 2022.08.20 |
c언어 2004번 조합 0의 개수 (백준) (0) | 2022.07.09 |
c언어 2606번 바이러스 (백준) (0) | 2022.06.27 |
c언어 14425번 문자열 집합 (백준) (0) | 2022.06.24 |
- Total
- Today
- Yesterday
- Lazy Propagation
- C언어
- Krustal
- 그리디
- 1835
- 덱
- 누적 합
- 정렬
- 기하학
- 백준
- 세그먼트 트리
- java
- C++
- 그래프
- DFS
- 브루트포스
- PASCAL
- 최대공약수
- 1835번
- 최소 스패닝 트리
- 누적합
- 플로이드
- BFS
- Segment Tree
- XOR
- 오프라인 쿼리
- find
- DP
- union
- 스택
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |