1. 문제 링크

 

https://www.acmicpc.net/problem/1919

 

1919번: 애너그램 만들기

두 영어 단어가 철자의 순서를 뒤바꾸어 같아질 수 있을 때, 그러한 두 단어를 서로 애너그램 관계에 있다고 한다. 예를 들면 occurs 라는 영어 단어와 succor 는 서로 애너그램 관계에 있는데, occurs�

www.acmicpc.net

 

 

 

2. 문제 설명

두 단어를 입력받은 후 서로 애너그램 관계에 있도록 만들기 위해서 제거해야하는 최소 개수의 문자 수를 출력하는 문제입니다.

 

 

 

3. 소스코드

BOJ 1919번 애너그램 만들기 C++ 풀이입니다.

#include <iostream>
#include <cmath>
using namespace std;

int main(void)
{
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);

	string s1, s2;
	int result = 0;
	int arr[26] = {};
	cin >> s1 >> s2;

	for (int i = 0; i < s1.length(); i++) arr[s1[i] - 'a']++;
	for (int i = 0; i < s2.length(); i++) arr[s2[i] - 'a']--;
	for (int i = 0; i < 26; i++) result += abs(arr[i]);
	cout << result;

	return 0;
}

s1에 있는 알파벳들은 arr배열의 해당 인덱스에 +1 해주고,

s2에 있는 알파벳들은 arr배열의 해당 인덱스에 -1 해줍니다.

arr배열의 요소가 0이 아닌 경우에는 삭제해야 애너그램을 만들 수 있으므로 절댓값만큼 result에 더해주면 됩니다.

'Algorithm > Study' 카테고리의 다른 글

[백준 10845번 C++] 큐  (1) 2020.05.21
[백준 10828번 C++] 스택  (0) 2020.05.21
[백준 5397번 C++] 키로거  (0) 2020.05.13
[백준 1158번 C++] 요세푸스 문제  (0) 2020.05.13
[백준 1475번 C++] 방 번호  (0) 2020.05.13

1. 문제 링크

 

https://www.acmicpc.net/problem/5397

 

5397번: 키로거

문제 창영이는 강산이의 비밀번호를 훔치기 위해서 강산이가 사용하는 컴퓨터에 키로거를 설치했다. 며칠을 기다린 끝에 창영이는 강산이가 비밀번호 창에 입력하는 글자를 얻어냈다. 키로거�

www.acmicpc.net

 

 

 

2. 문제 설명

키보드를 누른 명령어를 입력받은 후 규칙에 따라 비밀번호를 출력하는 문제입니다.

 

 

 

3. 소스코드

BOJ 5397번 키로거 C++ 풀이입니다.

#include <iostream>
#include <list>
using namespace std;

int main(void)
{
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);

	int T;
	list<char> l;
	list<char>::iterator t;
	string L;
	cin >> T;

	for (int i = 0; i < T; i++) {
		cin >> L;
		l.clear();
		t = l.begin();
		for (int j = 0; j < L.length(); j++) {
			if (L[j] == '<' && t != l.begin()) t--;
			else if (L[j] == '>' && t != l.end()) t++;
			else if (L[j] == '-' && t != l.begin()) t = l.erase(--t);
			else if (L[j] != '<' && L[j] != '>' && L[j] != '-') l.insert(t, L[j]);
		}
		for (t = l.begin(); t != l.end(); t++) cout << *t;
		cout << '\n';
	}

	return 0;
}

string L을 for문으로 돌면서 list l에 insert하거나 erase하는 방식으로 풀었습니다.

우선, 각 케이스마다 list를 초기화해줘야 하므로 18번 라인에서 clear함수로 초기화했습니다.

iterator t는 l.begin()으로 초기화해줬지만, 현재 list가 비어있어 l.begin() == l.end()이므로 아무거나 사용해도 됩니다.

L의 길이만큼 안쪽 for문을 돌면서 각각의 케이스에 맞게 l의 iterator인 t를 움직이거나, erase하거나, insert해주면 됩니다.

이 과정이 잘 이해가 되지 않는다면 비슷한 문제인 1406번 에디터 문제를 풀어보시면 좋을 것 같습니다.

해당 문제의 제 풀이는 아래와 같습니다. https://congcoding.tistory.com/43 

 

[백준 1406번 C++] 에디터

1. 문제 링크 https://www.acmicpc.net/problem/1406 1406번: 에디터 문제 한 줄로 된 간단한 에디터를 구현하려고 한다. 이 편집기는 영어 소문자만을 기록할 수 있는 편집기로, 최대 600,000글자까지 입력할 ��

congcoding.tistory.com

 

'Algorithm > Study' 카테고리의 다른 글

[백준 10828번 C++] 스택  (0) 2020.05.21
[백준 1919번 C++] 애너그램 만들기  (0) 2020.05.13
[백준 1158번 C++] 요세푸스 문제  (0) 2020.05.13
[백준 1475번 C++] 방 번호  (0) 2020.05.13
[백준 13300번 C++] 방 배정  (0) 2020.05.13

1. 문제 링크

 

https://www.acmicpc.net/problem/1158

 

1158번: 요세푸스 문제

첫째 줄에 N과 K가 빈 칸을 사이에 두고 순서대로 주어진다. (1 ≤ K ≤ N ≤ 5,000)

www.acmicpc.net

 

 

 

2. 문제 설명

N명의 사람이 원형으로 앉아있을 때 순서대로 K번째 사람을 제거하는 순서를 출력하는 문제입니다.

 

 

 

3. 소스코드

BOJ 1158번 요세푸스 문제 C++ 풀이입니다.

#include <iostream>
#include <vector>
using namespace std;

int main(void)
{
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);

	int N, K, idx;
	cin >> N >> K;
	vector<int> v(N);
	idx = K - 1;

	for (int i = 0; i < N; i++) v[i] = i + 1;
	cout << '<';
	while (v.size() != 1) {
		cout << v[idx] << ", ";
		v.erase(v.begin() + idx);
		idx = (idx + K - 1) % v.size();
	}
	cout << v[0] << '>';

	return 0;
}

먼저 vector와 인덱스를 이용한 풀이입니다.

인덱스는 0부터 시작하므로 13번 라인에서 idx를 K - 1로 초기화했습니다.

마지막 요소를 출력할 때는 ", "를 출력하지 않으므로 while문의 조건을 v.size() != 1로 설정했습니다.

먼저 idx에 있는 요소를 출력한 후, erase합니다.

idx를 K - 1만큼 증가시켰을 때, v의 범위를 초과하는 경우가 있으므로 size로 나눴을 때의 나머지를 대입합니다.

마지막으로 남은 요소를 출력하고 '>'를 같이 출력합니다.

 

 

 

#include <iostream>
#include <vector>
using namespace std;

int main(void)
{
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);

	int N, K, idx;
	cin >> N >> K;
	vector<int> v(N);
	vector<int>::iterator t = v.begin();
	for (int i = 0; i < N; i++) v[i] = i + 1;

	cout << '<';
	for (int i = 0; i < N - 1; i++) {
		for (int j = 0; j < K - 1; j++)
			if (++t == v.end()) t = v.begin();
		cout << *t << ", ";
		t = v.erase(t);
		if (t == v.end()) t = v.begin();
	}
	cout << v[0] << '>';

	return 0;
}

vector와 iterator를 이용한 풀이입니다.

마지막 요소를 출력할 때는 ", "를 출력하지 않으므로 바깥쪽 for문을 N - 1전까지만 돌게 설정했습니다.

vector와 index를 이용한 풀이처럼 while문의 조건을 v.size != 1로 설정해도 됩니다.

안쪽 for문은 K - 1번 돌면서 t를 한칸씩 이동시켜줍니다.

이 때 t가 end에 도달하면 v.begin()을 대입해줍니다. 원형이라고 생각하면 이해하기 쉽습니다.

현재 t위치의 요소를 출력한 후, 삭제(v.erase(t))를 해줍니다.

erase함수는 삭제한 요소의 다음 요소를 return하므로 이를 다시 t에 대입했습니다.

이 때 t가 end에 도달했을 경우 v.begin()을 대입해줍니다.

이 과정을 생략하면 안쪽 for문을 돌 때 ++t하는 과정에서 segmentation fault가 발생하므로 주의해야 합니다.

 

 

#include <iostream>
#include <list>
using namespace std;

int main(void)
{
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);

	int N, K, idx;
	cin >> N >> K;
	list<int> l;

	for (int i = 0; i < N; i++) l.push_back(i + 1);
	cout << '<';
	for (int i = 0; i < N - 1; i++) {
		for (int j = 0; j < K - 1; j++) {
			l.push_back(l.front());
			l.pop_front();
		}
		cout << l.front() << ", ";
		l.pop_front();
	}
	cout << l.front() << '>';

	return 0;
}

list 이용한 풀이입니다.

마지막 요소를 출력할 때는 ", "를 출력하지 않으므로 바깥쪽 for문을 N - 1전까지만 돌게 설정했습니다.

vector와 인덱스를 이용한 풀이처럼 while문의 조건을 l.size != 1로 설정해도 됩니다.

안쪽 for문은 K - 1번씩 돌면서 list의 맨 앞에 있는 요소를 맨 뒤로 옮겨줬습니다.

이를 구현하려면 맨 앞에 있는 요소(l.front())를 맨 뒤에 넣고(l.push_back), 맨 앞의 요소를 삭제(l.pop_front())하면 됩니다.

뒤로 다 옮긴 후 맨 앞에 있는 요소(l.front())를 출력한 후, 맨 앞의 요소를 삭제(l.pop_front())하면 됩니다.

'Algorithm > Study' 카테고리의 다른 글

[백준 1919번 C++] 애너그램 만들기  (0) 2020.05.13
[백준 5397번 C++] 키로거  (0) 2020.05.13
[백준 1475번 C++] 방 번호  (0) 2020.05.13
[백준 13300번 C++] 방 배정  (0) 2020.05.13
[백준 11328번 C++] Strfry  (0) 2020.05.13

1. 문제 링크

https://www.acmicpc.net/problem/1475

 

1475번: 방 번호

첫째 줄에 다솜이의 방 번호 N이 주어진다. N은 1,000,000보다 작거나 같은 자연수 또는 0이다.

www.acmicpc.net

 

 

 

2. 문제 설명

숫자를 입력받은 후 이를 표현하기 위해 0부터 9까지 숫자가 하나씩 들어있는 세트의 최소 필요 개수를 출력하는 문제입니다.

 

 

 

3. 소스코드

BOJ 1475번 방 번호 C++ 풀이입니다.

#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;

int main(void)
{
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);

	int N;
	vector<int> v(9);
	cin >> N;

	if (N == 0) v[0]++;
	while (N > 0) {
		if (N % 10 == 9) v[6]++;
		else v[N % 10]++;
		N /= 10;
	}
	v[6] = ceil((double)v[6] / 2);
	cout << *max_element(v.begin(), v.end());

	return 0;
}

6은 9를 뒤집어서 이용할 수 있기 때문에 9를 입력받으면 6의 자리에 +1을 해줬습니다.

한 세트에 6과 9가 들어있으므로 v[6]은 /2를 해준 후 ceil함수를 이용해 올림했습니다.

마지막으로 max_element함수를 이용해 최댓값을 출력해주면 됩니다.

'Algorithm > Study' 카테고리의 다른 글

[백준 5397번 C++] 키로거  (0) 2020.05.13
[백준 1158번 C++] 요세푸스 문제  (0) 2020.05.13
[백준 13300번 C++] 방 배정  (0) 2020.05.13
[백준 11328번 C++] Strfry  (0) 2020.05.13
[백준 1406번 C++] 에디터  (0) 2020.05.13

1. 문제 링크

 

https://www.acmicpc.net/problem/13300

 

13300번: 방 배정

표준 입력으로 다음 정보가 주어진다. 첫 번째 줄에는 수학여행에 참가하는 학생 수를 나타내는 정수 N(1 ≤ N ≤ 1,000)과 한 방에 배정할 수 있는 최대 인원 수 K(1 < K ≤ 1,000)가 공백으로 분리되어

www.acmicpc.net

 

 

 

2. 문제 설명

수학여행에 참가하는 학생의 정보를 입력받아, 학년과 성별로 방을 배정할 때 필요한 최소한의 방의 수를 출력하는 문제입니다.

 

 

 

3. 소스코드

BOJ 13300번 방 배정 C++ 풀이입니다.

#include <iostream>
#include <cmath>
using namespace std;

int main(void)
{
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);

	int N, K, r, c, result = 0;
	int arr[2][6] = {};
	cin >> N >> K;

	for (int i = 0; i < N; i++) {
		cin >> r >> c;
		arr[r][c - 1]++;
	}
	for (int i = 0; i < 2; i++) {
		for (int j = 0; j < 6; j++) {
			result += ceil((double)arr[i][j] / K);
		}
	}
	cout << result;

	return 0;
}

학생의 정보를 성별과 학년으로 저장하기 위해 11번 라인에서 arr[2][6]을 선언하고 0으로 초기했습니다.

학생의 성별은 0, 1이지만 학년이 1부터 6까지 이므로 arr에 학년 정보를 저장할 때는 -1을 해줬습니다.

arr의 각 요소들을 방에 배정할 수 있는 최대 인원 수로 나누고 ceil함수를 이용해서 올림해줬습니다.

이때 arr[i][j]나 K를 double로 형변환해주지 않으면 int끼리 연산돼서 이미 내림된 결과에

ceil함수를 적용하는 것이기 때문에 올림이 되지 않으니 주의해야 합니다.

'Algorithm > Study' 카테고리의 다른 글

[백준 1158번 C++] 요세푸스 문제  (0) 2020.05.13
[백준 1475번 C++] 방 번호  (0) 2020.05.13
[백준 11328번 C++] Strfry  (0) 2020.05.13
[백준 1406번 C++] 에디터  (0) 2020.05.13
[백준 10807번 C++] 개수 세기  (0) 2020.05.12

1. 문제 링크

 

https://www.acmicpc.net/problem/11328

 

11328번: Strfry

문제 C 언어 프로그래밍에서 문자열(string)은 native한 자료형이 아니다. 사실, 문자열은 그저, 문자열의 끝을 표시하기 위한 말단의 NULL이 사용된, 문자들로 이루어진 문자열일 뿐이다. 하지만 프��

www.acmicpc.net

 

 

 

2. 문제 설명

string을 2개씩 입력받은 후 서로 재배열할 수 있는지 여부를 출력하는 문제입니다.

 

 

 

3. 소스코드

BOJ 11328번 Strfry C++ 풀이입니다.

#include <iostream>
using namespace std;

int main(void)
{
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);

	int N;
	int arr[26];
	bool is_possible;
	string s1, s2;
	cin >> N;

	for (int i = 0; i < N; i++) {
		cin >> s1 >> s2;
		is_possible = true;
		fill(arr, arr + 26, 0);
		for (int j = 0; j < s1.length(); j++) {
			arr[s1[j] - 'a']++;
			arr[s2[j] - 'a']--;
		}
		for (int j = 0; j < 26; j++) {
			if (arr[j] != 0) {
				is_possible = false;
				break;
			}
		}
		if (is_possible) cout << "Possible\n";
		else cout << "Impossible\n";
	}

	return 0;
}

알파벳의 개수를 세기 위하여 10번 라인에서 arr[26]을 선언했습니다.

for문을 돌 때 마다 arr을 0으로 초기화하기 위해 18번 라인에서 fill함수를 사용했습니다.

문자열의 길이만큼 for문을 돌면서 s1에 있는 알파벳들의 인덱스에는 +1을 해주고

s2에 있는 알파벳들의 인덱스에는 -1을 해줬습니다.

결과적으로 arr의 요소가 0이 아니면 재배열해서 만들 수 없는 문자열이므로 이를 is_possible 변수를 이용해서 판단했습니다. 

'Algorithm > Study' 카테고리의 다른 글

[백준 1475번 C++] 방 번호  (0) 2020.05.13
[백준 13300번 C++] 방 배정  (0) 2020.05.13
[백준 1406번 C++] 에디터  (0) 2020.05.13
[백준 10807번 C++] 개수 세기  (0) 2020.05.12
[백준 10808번 C++] 알파벳 개수  (0) 2020.05.12

1. 문제 링크

 

https://www.acmicpc.net/problem/1406

 

1406번: 에디터

문제 한 줄로 된 간단한 에디터를 구현하려고 한다. 이 편집기는 영어 소문자만을 기록할 수 있는 편집기로, 최대 600,000글자까지 입력할 수 있다. 이 편집기에는 '커서'라는 것이 있는데, 커서는

www.acmicpc.net

 

 

 

2. 문제 설명

string을 입력받은 후 명령어에 따라 기능을 수행한 후 남아있는 string을 출력하는 문제입니다.

 

 

 

3. 소스코드

BOJ 1406번 에디터 C++ 풀이입니다.

#include <iostream>
#include <list>
using namespace std;

int main(void)
{
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);

	string s;
	char op;
	int M;
	cin >> s >> M;
	list<char> l(s.begin(), s.end());
	list<char>::iterator t = l.end();
	// auto t = l.end();

	for (int i = 0; i < M; i++) {
		cin >> op;
		if (op == 'L' && t != l.begin()) t--;
		else if (op == 'D' && t != l.end()) t++;
		else if (op == 'B' && t != l.begin()) t = l.erase(--t);
		else if (op == 'P') {
			cin >> op;
			l.insert(t, op);
		}
	}
	for (t = l.begin(); t != l.end(); t++) cout << *t;
	// for (auto c : l) cout << c;

	return 0;
}

연결 리스트를 사용하면 쉽게 풀 수 있는 문제이므로 14번 라인에서 입력받은 문자열을 list<char>에 대입했습니다.

문제에서 커서는 문장의 맨 뒤에 위치하고 있다고 했기 때문에 15번 라인에서 iterator t를 l.end()로 초기화했습니다.

16번 라인처럼 auto를 사용해도 됩니다.

 

명령어가 L이고 커서가 문장의 맨 앞(l.begin())이 아니면 커서를 한칸 앞으로 이동합니다. (t--)

명령어가 D이고 커서가 문장의 맨 뒤(l.end())가 아니면 커서를 한칸 뒤로 이동합니다. (t++)

 

명령어가 B이고 커서가 문장의 맨 앞(l.begin())이 아니면 커서 왼쪽에 있는 문자(--t)를 삭제합니다.

list의 erase함수를 사용할 때 return값은 지운 요소의 다음 요소를 반환하므로 이를 다시 t에 대입해줍니다.

return값을 활용하지 않으려면 t--; l.erase(t++);과 같이 사용하면 됩니다.

 

명령어가 P이면 커서 왼쪽에 문자를 추가하므로 t위치에 insert하면 됩니다.

list의 insert함수는 iterator가 가리키는 곳의 왼쪽에 삽입하고, iterator는 원래 요소를 그대로 가리킵니다.

 

리스트를 출력하는 방법은 28번 라인처럼 for문에 iterator를 사용하면 됩니다.

29번 라인처럼 auto를 사용해도 됩니다. 

'Algorithm > Study' 카테고리의 다른 글

[백준 13300번 C++] 방 배정  (0) 2020.05.13
[백준 11328번 C++] Strfry  (0) 2020.05.13
[백준 10807번 C++] 개수 세기  (0) 2020.05.12
[백준 10808번 C++] 알파벳 개수  (0) 2020.05.12
[백준 2446번 C++] 별 찍기 - 9  (0) 2020.04.30

1. 문제 링크

 

https://www.acmicpc.net/problem/10807

 

10807번: 개수 세기

첫째 줄에 정수의 개수 N(1 ≤ N ≤ 100)이 주어진다. 둘째 줄에는 정수가 공백으로 구분되어져있다. 셋째 줄에는 찾으려고 하는 정수 v가 주어진다. 입력으로 주어지는 정수와 v는 -100보다 크거나 같으며, 100보다 작거나 같다.

www.acmicpc.net

 

 

 

2. 문제 설명

N개의 정수를 입력받은 후, 찾으려고 하는 정수 v가 몇 개인지 출력하는 문제입니다.

 

 

 

3. 소스코드

BOJ 10807번 개수 세기 C++ 풀이입니다.

#include <iostream>
using namespace std;

int main(void)
{
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);

	int N, num, v;
	int arr[201] = {};
	cin >> N;

	for (int i = 0; i < N; i++) {
		cin >> num;
		arr[num + 100]++;
	}
	cin >> v;
	cout << arr[v + 100];

	return 0;
}

입력으로 주어지는 정수와 v는 -100보다 크거나 같고, 100보다 작거나 같으므로

10번 라인에서 arr[201]로 선언 후 0으로 초기화 했습니다.

배열의 인덱스는 0부터 시작하므로 -100일 때 0번 인덱스에 저장하기 위해서 15번 라인처럼 +100을 해줍니다.

마찬가지로 출력할 때도 18번 라인처럼 +100을 해주면 됩니다.

'Algorithm > Study' 카테고리의 다른 글

[백준 11328번 C++] Strfry  (0) 2020.05.13
[백준 1406번 C++] 에디터  (0) 2020.05.13
[백준 10808번 C++] 알파벳 개수  (0) 2020.05.12
[백준 2446번 C++] 별 찍기 - 9  (0) 2020.04.30
[백준 2445번 C++] 별 찍기 - 8  (0) 2020.04.30

1. 문제 링크

https://www.acmicpc.net/problem/10808

 

10808번: 알파벳 개수

단어에 포함되어 있는 a의 개수, b의 개수, …, z의 개수를 공백으로 구분해서 출력한다.

www.acmicpc.net

 

 

 

2. 문제 설명

string을 입력받은 후 단어에 포함되어 있는 알파벳의 개수를 각각 출력하는 문제입니다.

 

 

 

3. 소스코드

BOJ 10808번 알파벳 개수 C++ 풀이입니다.

#include <iostream>
using namespace std;

int main(void)
{
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);

	int arr[26] = {};
	string S;
	cin >> S;

	for (int i = 0; i < S.length(); i++) arr[S[i] - 'a']++;
    // for (auto s : S) arr[s - 'a']++;
	for (int i = 0; i < 26; i++) cout << arr[i] << ' ';

	return 0;
}

9번 라인에서 arr배열을 0으로 초기화해주기 위해 {}을 사용했습니다.

13번 라인 for문에서 string을 한칸씩 돌면서 해당하는 arr의 인덱스의 값을 증가시켜주고,

15번 라인 for문으로 arr을 출력하면 됩니다.

13번 라인은 auto를 사용하면 14번 라인처럼 써도 됩니다.

'Algorithm > Study' 카테고리의 다른 글

[백준 1406번 C++] 에디터  (0) 2020.05.13
[백준 10807번 C++] 개수 세기  (0) 2020.05.12
[백준 2446번 C++] 별 찍기 - 9  (0) 2020.04.30
[백준 2445번 C++] 별 찍기 - 8  (0) 2020.04.30
[백준 2444번 C++] 별 찍기 - 7  (0) 2020.04.30

+ Recent posts