일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Bronze
- two pointer
- Project
- level3
- stack
- Zenject
- 3D RPG
- 프로그래머스
- BOJ
- Euclidean
- binary search
- PrefixSum
- 프로세스 상태
- Flyweight Pattern
- programmers
- Gold
- Modern C++
- 8-Puzzle
- dirtyflag pattern
- Silver
- effective C++
- LEVEL2
- solid 원칙
- SWEA
- knapsack Problem
- level1
- trie
- Unity
- algorithm
- BFS
- Today
- Total
Patrick's Devlog
[BOJ/C++] 성냥 개비(3687번) 본문
1. 개요
https://acmicpc.net/problem/3687
1-1. 설명
성냥개비로 위와 같은 숫자를 만드려고한다. 성냥개비의 개수가 주어졌을 때, 성냥 개비를 모두 사용해 만들 수 있는 가장 작은 수와 큰 수를 찾는 프로그램을 작성한다.
1-2. 제한 사항
- 첫 줄에 테스트 케이스 개수가 주어지며, 최대 100개
- 각 테스트 케이스는 한줄로 이루어져 있고, 성냥개비 개수 n이 주어짐
- n 은 2 이상 100 이하의 자연수
- 각 테스트 케이스에 대해 입력으로 주어진 성냥 개비를 모두 사용해서 만들 수 있는 가장 작은 수와 큰 수를 출력
2. 구현
2-1. 풀이
큰 수는 자릿수가 많을수록 커지므로, 1과 7을 이용하여 만든다. 1은 2개, 7은 3개로 다른 숫자들은 4개 이상이므로 1과 7을 이용하면 된다.
- n이 짝수인 경우 : 1로만 배치
- n이 홀수인 경우 : 1로 배치 후 맨 앞 자리수를 7로 변경
작은 수는 다이나믹 프로그래밍을 통해 구해야 한다. 성냥개비의 개수 2~100개 까지를 dp 배열에 저장하고 100까지 반복문을 통해 작은 수를 계산한다. 성냥개비 개수인 2~8개까지는 각각 숫자에 맞게끔 초기화를 시켜준다.
long long dp[MAX_COUNT] = { 0, 0, 1, 7, 4, 2, 6, 8, 10 };
여기서 한자리수는 0이 최솟값이 되면 안되므로, 성냥개비가 6개일때는 6이 들어가게 된다. 이후에 dp 배열을 통해 최솟값을 계산할 배열을 선언 및 초기화 한다
int fireStickArray[6] = {1, 7, 4, 2, 0, 8};
반복문은 9로 시작하여, 각 dp[i]에서 2~7개의 성냥개비 개수를 통해 최솟값을 구해야 한다.
long long cur = (dp[i - j] * 10) + fireStickArray[j - 2];
j == 2 ? (dp[i] = cur) : (dp[i] = min(dp[i], cur));
// example > 9개일 때
// dp[9-2] * 10 + fireStickArray[0] (성냥 개수 : 7 + 2)
// dp[9-3] * 10 + fireStickArray[1] (성냥 개수 : 6 + 3)
// ...
// dp[9-7] * 10 + fireStickArray[7] (성냥개수 : 2 + 7)
// (* 10)은 자릿수 추가를 위함
// 계산 후 2~7개 중에서 최솟값을 dp[9]에 저장
최솟값을 n이 100개인 경우까지 구해서 테스트 케이스를 받을 때마다 dp[n]을 출력해주면 된다.
2-2. 코드
#include <iostream>
#include <algorithm>
#define MAX_COUNT 101
using namespace std;
long long dp[MAX_COUNT] = { 0, 0, 1, 7, 4, 2, 6, 8, 10 };
int fireStickArray[6] = {1, 7, 4, 2, 0, 8};
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int tc, n;
string max;
cin >> tc;
// dynamic programming
for (int i = 9; i < MAX_COUNT; i++) {
for (int j = 2; j <= 7; j++) {
long long cur = (dp[i - j] * 10) + fireStickArray[j - 2];
j == 2 ? (dp[i] = cur) : (dp[i] = min(dp[i], cur));
// 성냥개비 2 ~ 7 범위에서 최솟값 계산
}
}
while (tc--)
{
cin >> n;
max = "";
// greedy algorithm
for (int i = 0; i < n / 2; i++) max += "1";
if (n % 2 == 1)
max[0] = '7';
// 최댓값 : 7,1로만 이루어짐 -> 자릿수가 많을수록 큰 숫자이므로
cout << dp[n] << ' ' << max << "\n";
}
}
참고 문서
백준 3687[자바] java 성냥개비
문제 링크: https://www.acmicpc.net/problem/3687 3687번: 성냥개비 각 테스트 케이스에 대해서 입력으로 주어진 성냥개비를 모두 사용해서 만들 수 있는 가장 작은 수와 가장 큰 수를 출력한다. 두 숫자는
dingdingmin-back-end-developer.tistory.com
'Algorithm > Algorithms Practice' 카테고리의 다른 글
[BOJ/C++] 주사위 굴리기(14499번) (0) | 2025.01.22 |
---|---|
[BOJ/C++] 토마토(7576번) (0) | 2024.08.13 |
[BOJ/C++] 옥상 정원 꾸미기(6198번) (1) | 2024.07.22 |
[BOJ/C++] 문제 추천 시스템 Version 1(21939번) (1) | 2024.02.07 |
[BOJ/C++] 문자열 집합 (1) | 2024.01.30 |