문제출처: https://www.acmicpc.net/problem/1855
문제
준표와 세준이는 서로 솔루션을 토론 하면서 다른 사람이 자신들의 솔루션을 듣지 못하게 하도록 서로 메시지를 주고받을 때 메시지를 암호화 하여서 주고받았다. 암호를 만드는 방법은 다음과 같다. 먼저 암호화 할 문자열을 1,1부터 위에서 아래 순서대로 채운다. 그리고 가장 밑의 행을 채운 후에는 오른쪽 열에서 다시 같은 과정을 반복한다.
만약에 "abcdefghijkl" 이라는 문자열을 3개의 열로 암호화 한다고 하자. 그러면 다음과 같이 표를 채울 수 있을 것이다.
a | e | i |
b | f | j |
c | g | k |
d | h | l |
그런 후에는 이제 왼쪽-> 오른쪽, 오른쪽-> 왼쪽, 왼쪽->오른쪽 ... 으로 읽으면서 다시 문자열을 만든다. 위의 경우에는 "aeijfbcgklhd" 가 될 것이다.
우리가 할 일은 다음과 같다. 암호화 된 문자열과 몇 개의 열로 암호화를 하였는지 주어져 있을 때 원래의 문자열을 구하는 프로그램을 작성하여라.
입력
열의 개수 K(1≤K≤20)가 주어지고 두 번째 줄에는 암호화 된 문자열(모두 영소문자)이 주어진다. (문자열의 길이는 200 이하이며 K의 배수이다.)
출력
첫 줄에 원래의 문자열을 출력한다..
풀이
이런 특정한 순서대로 입력된 수를 다시 출력 하는문제들은 노트에 대고 규칙을 찾아보면 금방 풀 수 있습니다.
문제에서 문자열의 최대길이는 200이고 열의 최대길이는 20이므로 행은 최대 10임을 알 수 있습니다. 곧, 문제의 표를 만들기 위한 2차원 배열의 사이즈는
map[10][20] 이 최대입니다. 저는 문제의 표를 만들고 규칙대로 풀었는데, 표를보면 짝수행은 정방향, 홀수행은 역방향으로 문자들이 이어집니다.
짝수행일 때 어떻게 표를 만들까요?
2행을 예로들면, map[2][0]=s[0], map[2][1]=s[7], map[2][2]=s[8]인데, 규칙을 보면 각 값들이 (행*k) + 0, (행,*k)+1, (행*k)+2의 규칙성을 볼 수 있습니다.
홀수행일 때 3행을 보면 map[3][0]=s[11], map[3][1]=s[10], map[3][2]=s[9]인데 각 값들이 (행*k)+2, (행*k)+1, (행*k)+0의 규칙성을 갖습니다.
이를 소스코드로 구현 후 조건대로 출력하면됩니다.
코드
#include<iostream> #include<string> using namespace std; char map[10][20]; int main() { int k; string s; cin >> k; cin >> s; for (int i = 0; i < s.size() / k; i++) { if(i%2==0)//짝수행 for (int j = 0; j < k; j++) { map[i][j] = s[i * k + j]; } else { int c = k - 1; for (int j = 0; j < k; j++) { map[i][j] = s[i*k+c]; c--; } } } for (int i = 0; i < k; i++) { for (int j = 0; j < s.size() / k; j++) { cout << map[j][i]; } } cout << endl; }
결과
'문제풀이(BOJ) > 규칙찾기' 카테고리의 다른 글
[백준 14954] Happy Number (0) | 2020.03.10 |
---|---|
[백준 1652] 누울 자리를 찾아라 (2) | 2020.01.15 |
[백준 3076] 상근이의 체스판 (0) | 2020.01.03 |
[백준 1551] 수열의 변화 (0) | 2020.01.03 |
[백준 10996] 별 찍기- 21 (0) | 2020.01.02 |