[BAEKJOON] 백준 1855: 암호 (C#)

2024. 5. 21. 16:54IT/BaekJoon

문제 링크

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

 

 

문제

준표와 세준이는 서로 솔루션을 토론 하면서 다른 사람이 자신들의 솔루션을 듣지 못하게 하도록 서로 메시지를 주고받을 때 메시지를 암호화 하여서 주고받았다. 암호를 만드는 방법은 다음과 같다. 먼저 암호화 할 문자열을 1,1부터 위에서 아래 순서대로 채운다. 그리고 가장 밑의 행을 채운 후에는 오른쪽 열에서 다시 같은 과정을 반복한다.

만약에 "abcdefghijkl" 이라는 문자열을 3개의 열로 암호화 한다고 하자. 그러면 다음과 같이 표를 채울 수 있을 것이다.

그런 후에는 이제 왼쪽 → 오른쪽, 오른쪽 → 왼쪽, 왼쪽 → 오른쪽 ... 으로 읽으면서 다시 문자열을 만든다. 위의 경우에는 "aeijfbcgklhd" 가 될 것이다.

우리가 할 일은 다음과 같다. 암호화 된 문자열과 몇 개의 열로 암호화를 하였는지 주어져 있을 때 원래의 문자열을 구하는 프로그램을 작성하여라.

 

 

입력

열의 개수 K(1 ≤ K ≤ 20)가 주어지고 두 번째 줄에는 암호화 된 문자열(모두 영소문자)이 주어진다. (문자열의 길이는 200 이하이며 K의 배수이다.)

 

 

출력

첫 줄에 원래의 문자열을 출력한다..

 

 

 

통과한 답안

using System.Text;

namespace _1855
{
    internal class Program
    {
        static void Main(string[] args)
        {
            int K = int.Parse(Console.ReadLine());
            string input = Console.ReadLine();

            int len = input.Length / K;
            char[,] alp = new char[len, K];

            for (int i = 0; i < len; i++)
            {
                for (int j = 0; j < K; j++)
                {
                    if (i % 2 == 0)
                    {
                        alp[i, j] = input[K * i + j];
                    }
                    else
                    {
                        alp[i, j] = input[K * (i + 1) - j - 1];
                    }
                }
            }

            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < K; i++)
            {
                for (int j = 0; j < len; j++)
                {
                    sb.Append(alp[j, i]);
                }
            }

            Console.WriteLine(sb.ToString());
        }
    }
}

 

주어진 문자열을 2번 암호화한 과정을 역으로 돌리는 코드를 구현하는 문제이다.

1번 암호화는 문자을 주어진 크기에 맞는 행렬에 세로로 입력하는 과정이고

2번 암호화는 홀수번째와 짝수번째의 행에는 방향이 반대가 되도록 하는 과정이다.

 

이를 해결하기 위해서 2차원 배열을 이용하였으며

행렬의 크기를 구하기 위해서 문자열의 길이를 주어진 열의 개수 K로 나눴다.

 

for (int i = 0; i < len; i++)
{
    for (int j = 0; j < K; j++)
    {
        if (i % 2 == 0)
        {
            alp[i, j] = input[K * i + j];
        }
        else
        {
            alp[i, j] = input[K * (i + 1) - j - 1];
        }
    }
}

 

2번 암호화를 풀기 위해서 위와 같이 짝수와 홀수인 경우에

방향이 반대로 되도록 2차원 배열에 입력되도록 코드를 작성했다.

(짝수번 인덱스는 왼쪽 -> 오른쪽, 홀수번 인덱스는 오른쪽 -> 왼쪽으로 입력된다)

 

StringBuilder sb = new StringBuilder();
for (int i = 0; i < K; i++)
{
    for (int j = 0; j < len; j++)
    {
        sb.Append(alp[j, i]);
    }
}

 

1번 암호화를 풀기 위해서 stringbuilder를 이용하였으며

세로로 받아오는 과정을 만들기 위해서 for문에서 행과 열을 반대로 사용하였다.