반응형

www.acmicpc.net/step/34

 

백트래킹 단계

조금 더 복잡한 백트래킹 문제 1

www.acmicpc.net

고등 확률과 통계에서 배우는 순열과 조합이다.

순열과 조합을 구현하는데에 있어 매번 구글링 하기 귀찮아 좋은 정보를 얻어 정리를 해보려고한다.

출처 : hongchan.tistory.com/5

 

[C++] 순열(Permutation) 조합(Combination) 알고리즘

백준에서 완전 탐색 문제를 풀다가 항상 조합과 순열을 만들 때 헷갈려서 아예 시간을 내어 정리하였다. 이 네 가지 알고리즘의 뼈대를 이해하면, 여러 방면에 쓰여서 좋은 거 같다. 이후 나오는

hongchan.tistory.com

덕분에 좋은 정보를 얻었다.

 

순열 nPr

void printArray(int a[], int r) {
    for (int i = 0;i < r;i++) {
        printf("%d ", a[i]);
    }
    printf("\n");
}

void permutation(int pArr[], bool check[], int n, int r, int depth) {
    if (depth == r) {
        printArray(pArr, r);
        return;
    }

    for (int i = 1; i <= n; i++) {
        if (!check[i]) {
            check[i] = true;
            pArr[depth] = i;
            permutation(pArr, check, n, r, depth + 1);
            check[i] = false;
        }
    }
}

int main(void) {

    int n, r;
    cin >> n >> r;
    int* pArr = new int[r];
    bool* check = new bool[n + 1];
    for (int i = 0;i < r;i++) {
        pArr[i] = 0;
    }
    for (int i = 0;i < n + 1;i++) {
        check[i] = false;
    }
    permutation(pArr, check, n, r, 0);

    return 0;
}
  1. pArr[] : n 까지의 숫자의 경우를 저장할 배열
  2. check[] : 순열에서 중복의 여부를 확인하는 배열 ( 이 배열을 뺀다면 중복 순열이 된다. )

알고리즘 설명

  1. check 가 false 인지 확인 ( 이미 나온 숫자인가? )
  2. false 이면 true 로 할당
  3. pArr[] 에 i 할당 ( 1부터 저장하기 위해 i = 1 로 지정 )
  4. Permutation(...,depth + 1) 실행하여 중복되지 않는 수를 확인하고 배열에 삽입
  5. depth == r 이 된다면 pArr 에 있는 원소 모두 출력
  6. check 를 차례대로 false 로 할당하면서 함수 빠져나옴
  7. for 문 반복

 

조합 nCr

void combination(int pArr[], int n, int r, int depth, int next) {
    if (depth == r) {
        printArray(pArr, r);
        return;
    }

    for (int i = next; i <= n; i++) {
        pArr[depth] = i;
        combination(pArr,n, r, depth + 1, i+1);// i+1 을 i로 바꿔주면 중복 허용
    }
}

int main(void) {

    int n, r;
    cin >> n >> r;
    int* pArr = new int[r];
    for (int i = 0;i < r;i++) {
        pArr[i] = 0;
    }
    combination(pArr, n, r, 0, 1);

    return 0;
}

순열과 다른 점 

  • 조합은 순열과 달리 오름차순으로 정렬이 된다.

따라서, for 문의 i 값이 combination 이 실행될 수록 이 전 i 값보다 커야한다.

그리고, check[] 배열을 사용하지 않는 이유는 i 값을 늘려줌으로써 이전의 i 값이나 동일한 값이 들어가지 않기 때문이다.

그래서, i 의 값을 유지시킨다면 중복 조합이 된다. 

 

재귀로된 순열과 조합을 설명해 보았다.

하지만, 재귀인만큼 큰 수로 접근하게 된다면 overflow 발생 가능성도 있고 무엇보다 느리다.

이와 관련된 문제를 풀었었는데 까먹었다. ㅎㅎ

반응형

'BOJ' 카테고리의 다른 글

[백준 1018번] 체스판 다시 칠하기  (0) 2021.05.03
[백준 11758번] CCW  (0) 2021.04.30
[백준 9012번] 괄호  (0) 2021.04.25
[백준 10773번] 제로  (0) 2021.04.22
[백준 1546번] 평균  (0) 2021.04.22
반응형

www.acmicpc.net/problem/9012

 

9012번: 괄호

괄호 문자열(Parenthesis String, PS)은 두 개의 괄호 기호인 ‘(’ 와 ‘)’ 만으로 구성되어 있는 문자열이다. 그 중에서 괄호의 모양이 바르게 구성된 문자열을 올바른 괄호 문자열(Valid PS, VPS)이라고

www.acmicpc.net

#include <iostream>
#include <stack>
#include <string>
using namespace std;

int main(void) {
	int i,T;
	stack<char> s1;
	cin >> T;
	string line;
	for (i = 0;i < T;i++) {
		cin >> line;

		for (int j = 0;j < line.size();j++) {
			char a;
			a = line.at(j);
			if(a == '(')
				s1.push(a);
			else if (a == ')') {
				if (!(s1.empty())) {
					if (s1.top() == '(')
						s1.pop();
				}
				else if (s1.empty())
					s1.push(a);
				else s1.push(a);
			}
		}
		if (s1.empty())cout << "YES"<<'\n';
		else {
			cout << "NO" << '\n';
			while (!s1.empty()) {
				s1.pop();
			}
		}
	}
	return 0;
}

2학년때 후위도 표기로 구현된 계산기를 만들때가 생각난 문제

조금 다른느낌이지만 괄호구현하는거 때문에 애가 탔었던 기억이 난다.

EZ

반응형

'BOJ' 카테고리의 다른 글

[백준 11758번] CCW  (0) 2021.04.30
[백준] 순열 & 조합 (Permutation & Combination)  (0) 2021.04.27
[백준 10773번] 제로  (0) 2021.04.22
[백준 1546번] 평균  (0) 2021.04.22
[백준 1003번] 피보나치 함수  (0) 2021.04.21
반응형

www.acmicpc.net/problem/10773

 

10773번: 제로

첫 번째 줄에 정수 K가 주어진다. (1 ≤ K ≤ 100,000) 이후 K개의 줄에 정수가 1개씩 주어진다. 정수는 0에서 1,000,000 사이의 값을 가지며, 정수가 "0" 일 경우에는 가장 최근에 쓴 수를 지우고, 아닐 경

www.acmicpc.net

#include <iostream>
#include <stack>

using namespace std;

int main(void) {
	int T, num;
	int sum = 0;

	cin >> T;
	int i;
	stack<int> number;
	for (i = 0;i < T;i++) {
		cin >> num;
		if (num != 0)
			number.push(num);
		else if (num == 0) {
			if (number.empty()) number.push(num);
			else number.pop();
		}
	}
	int size =number.size();
	for (i = 0;i < size;i++) {
		sum += number.top();
		number.pop();
	}
	cout << sum;
	return 0;
}

힌트를 안보고 풀다가 좀 헤맸는데 결국 풀어냈다.

스택에 전부 집어넣고 하다가 안풀려서 생각의 전환을 해봤다.

그래서 히히 난 천재야 하며 즐거워했지만

밑에 힌트가 있었다는게 함정이었다.ㅠㅠ

반응형

'BOJ' 카테고리의 다른 글

[백준 11758번] CCW  (0) 2021.04.30
[백준] 순열 & 조합 (Permutation & Combination)  (0) 2021.04.27
[백준 9012번] 괄호  (0) 2021.04.25
[백준 1546번] 평균  (0) 2021.04.22
[백준 1003번] 피보나치 함수  (0) 2021.04.21
반응형

www.acmicpc.net/problem/1546

 

1546번: 평균

첫째 줄에 시험 본 과목의 개수 N이 주어진다. 이 값은 1000보다 작거나 같다. 둘째 줄에 세준이의 현재 성적이 주어진다. 이 값은 100보다 작거나 같은 음이 아닌 정수이고, 적어도 하나의 값은 0보

www.acmicpc.net

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main(void) {
	double T,i;
	double num, max;
	double sum = 0.0;
	cin >> T;
	vector<double> mean;
	for (i = 0;i < T;i++) {
		cin >> num;
		mean.push_back(num);
		
	}
	max = *max_element(mean.begin(), mean.end());
	//cout << max << '\n';
	for (i = 0;i < T;i++) {
			mean[i] = mean[i] / max * 100;
	}
	for (i = 0;i < T;i++) {
		sum += mean[i];
	}
	cout << sum / T;
	return 0;
}

처음에는 되게 쉽다고 시작했는데

중간에 이상한 코드를 하나 짜서 나의 능지에 의심을 품었지만 찾아버리고 말았다.

하지만 브론즈 1문제 였고..

아직 갈길이 멀다.

얼른 실버 찍어야징

반응형

'BOJ' 카테고리의 다른 글

[백준 11758번] CCW  (0) 2021.04.30
[백준] 순열 & 조합 (Permutation & Combination)  (0) 2021.04.27
[백준 9012번] 괄호  (0) 2021.04.25
[백준 10773번] 제로  (0) 2021.04.22
[백준 1003번] 피보나치 함수  (0) 2021.04.21

+ Recent posts