fragment-header
fragment-markdown
홈
로그인
로그아웃
내 블로그
설정
로그인
백준 13392 (C++) 방법을 출력하지 않는 숫자 맞추기
최초 업로드: 2025-04-30 02:41:28
최근 수정 시간: 2025-07-25 08:51:43
게시자: rlatjwls3333
카테고리: 백준
조회수: 9
# [Gold I] 방법을 출력하지 않는 숫자 맞추기 [문제 링크](https://www.acmicpc.net/problem/13392) ## 문제 설명 <p>아래 그림과 같이 N개의 회전이 가능한 숫자 나사가 아래위로 연결되어 있다. 가장 위에 있는 숫자나사는 숫자나사 1이고 가장 아래에 있는 숫자나사는 숫자나사 N이다. 모든 숫자나사는 각각 10개의 면을 가지고 있고, 각 면에는 오른쪽 방향으로 0, 1, 2, 3, …, 9까지의 숫자가 하나씩 순서대로 적혀 있다. 하나의 숫자나사를 왼쪽으로 회전 시키면, 이 나사보다 아래에 위치한 모든 나사는 같이 따라서 돌게 되지만, 나사를 오른쪽으로 회전시키면, 다른 나사는 함께 돌지는 않는다. 정면에서 보아 위에서부터 아래쪽으로 숫자를 읽어 내려간다고 할 때, 현재의 상태에서 가장 적은 칸수의 움직임으로 원하는 숫자를 만들기 위한 방법을 출력하는 프로그램을 작성하라.</p> <p>예를 들어 세 개의 숫자나사가 주어졌을 때, 정면에서 보는 현재 상태가 326이고 원하는 상태는 446이라면 최소 회전 칸수는 4이다. 먼저 숫자나사 1을 왼쪽으로 한 칸 돌리면 437이 되고, 숫자나사 2를 역시 왼쪽으로 한 칸 돌리면 448이 되며, 마지막으로 숫자나사 3을 오른쪽으로 두 칸 돌리면 446이 된다.</p> <p style="text-align: center;"><img alt="" src="https://upload.acmicpc.net/62a0dbc7-5004-46d4-824d-12b434a3b71d/-/preview/" style="width: 248px; height: 256px;"></p> ## 입력 <p>첫째 줄에는 숫자나사의 개수 N이 주어지고, 둘째 줄에는 현재의 상태가, 셋째 줄에는 원하는 상태가 주어진다. N은 3 이상이고 10,000 이하이다.</p> ## 출력 <p>첫째 줄에는 현재 상태에서 원하는 상태로 도달하는데 필요한 최소 회전 칸수를 출력한다.</p> ## 풀이 #### 왼쪽으로 돌린 상태는 0~9 사이에서 전부 나타내진다. 그래서 dp[i][j]를 i번째 숫자나사에서 왼쪽으로 j번 돌렸을 때의 최소 회전 칸수로 두고 풀었다. ``` c++ #include<bits/stdc++.h> using namespace std; const int INF = 0x3f3f3f3f; // dp[i][j] : i번째 나사에 대하여, 총 왼쪽으로 j%10번 돌렸을 때의 최소 회전 수 int dp[10001][10]; int main() { ios::sync_with_stdio(0); cin.tie(0); int n; string a, b; cin >> n >> a >> b; fill(&dp[0][0], &dp[10000][10], INF); dp[0][0]=0; for(int i=1;i<=n;i++) { for(int j=0;j<10;j++) { char cur = a[i-1]+j; // 오른쪽으로 돌리기 (a[i-1]이 작아짐) int rightCnt = ((a[i-1]-'0'+j)%10 + (10-(b[i-1]-'0')))%10; dp[i][j] = min(dp[i][j], dp[i-1][j] + rightCnt); // 왼쪽으로 돌리기 (a[i-1]이 커짐) int leftCnt = ((b[i-1]-'0') + 10-(a[i-1]-'0'+j)%10)%10; dp[i][(j+leftCnt)%10] = min(dp[i][(j+leftCnt)%10], dp[i-1][j] + leftCnt); } } int minCnt = INF; for(int i=0;i<10;i++) minCnt = min(minCnt, dp[n][i]); cout << minCnt; } ```