728x90
개요
문제 링크
실버 1, Greedy
nC2만큼의 서로 다른 원소쌍 중 사전 순이 가장 빠른 방법 출력
접근
- 어렵게 푸는 문제인가? 싶었는데 생각해보면 크게 복잡하지 않음. 인접행렬 이용한다 생각하면 단순했음.
- 만약 (a1, a2)를 출력했다면 (a1, a2)는 다시 출력하면 안됨. 인접행렬에서 연결 여/부를 부로 바꿔주면 됨.
- 다음 것을 출력할 때 사전순으로 가장 빠른 것을 출력하려면? 1부터 걍 완탐하면서 인접행렬이 연결되어있다면 출력해주면 됨. 그리고 출력한 점을 다음 점으로 업데이트
- 그런데 3번까지만 해주면 아래와 같은 오류 생김
그래서 (ai, aj)의 연결선이 남아있다면, aj의 연결선이 하나라도 남아있는지, 즉 진행이 가능한지 확인을 해줘야함.N = 5 a1 -> a2 -> a3 -> a1 -> a4 -> a2 -> a5 -> a1 // a5-a1의 연결선은 남아있지만, a1의 다음 연결선이 남아있지 않음 // nC2만큼 진행이 안되고 중간에 끊긴다.
Pseudo code
int get_next(i) {
for (j = 1~n)
if (인접행렬에 [i, j] 없으면)
continue
if (j에 남은 연결선 수가 1개)
continue
인접행렬[i, j] = 0
인접행렬[j, i] = 0
남은연결선[i]--
남은연결선[j]--
return j;
}
현재 = get_next(현재)
Source code
#include <bits/stdc++.h>
using namespace std;
const int N = 510;
int n;
int a[N][N], b[N];
int print(int i) {
for (int j=1; j<=n; j++)
if (a[i][j] && 1<b[j]) {
a[i][j] = 0;
a[j][i] = 0;
b[i]--;
b[j]--;
return j;
}
return -1;
}
int main() {
cin >> n;
for (int i=1; i<=n; i++) {
for (int j=1; j<=n; j++)
a[i][j] = 1;
a[i][i] = 0;
b[i] = n-1;
}
int cnt = n*(n-1)/2;
int s = 1;
while (cnt--) {
printf("a%d ", s);
s = print(s);
}
printf("a%d ", 1);
}
728x90
'백준브실골 > Greedy' 카테고리의 다른 글
백준 12237, Up and Down (Large) (0) | 2023.02.09 |
---|---|
백준 13884, 삭삽 정렬 (0) | 2023.02.08 |
백준 4889, 안정적인 문자열 (0) | 2023.02.08 |
백준 9009, 피보나치 (0) | 2023.02.08 |
백준 25683, 행렬 곱셈 순서 4 (0) | 2023.02.08 |
백준 23758, 중앙값 제거 (0) | 2023.02.08 |
백준 1105, 팔 (0) | 2023.02.08 |
백준 1263, 시간 관리 (0) | 2023.02.08 |
댓글