작성일 :

문제 링크

6260번 - Encrypted SMS

설명

휴대폰 멀티탭 입력에서 문자별 키와 눌림 횟수가 정해집니다. 키패드는 2번부터 9번까지 각각 ABC, DEF, GHI, JKL, MNO, PQRS, TUV, WXYZ가 배치되어 있습니다.

암호화는 원문의 i번째 문자에서 사용 키를 i번 더 눌러 다음 문자로 순환 이동해 암호문을 만듭니다. 복호화는 반대로, 암호문의 i번째 문자를 키 안에서 되돌리면 됩니다.


접근법

먼저, 대문자 그룹 배열과 소문자 그룹 배열을 준비하고 문자가 속한 그룹과 위치를 찾습니다.

다음으로, i번째 문자의 시프트는 i+1입니다. 현재 위치에서 시프트를 빼고 그룹 길이로 나눈 나머지를 구합니다. 음수가 되면 그룹 길이를 더해 보정합니다.

이후, 찾은 그룹에서 대소문자를 그대로 유지하며 원래 문자를 출력합니다.



Code

C#

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
31
32
33
34
35
36
37
38
39
40
41
42
43
using System;

namespace Solution {
  class Program {
    static void Main(string[] args) {
      var up = new string[] { "ABC", "DEF", "GHI", "JKL", "MNO", "PQRS", "TUV", "WXYZ" };
      var lo = new string[] { "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };

      while (true) {
        var s = Console.ReadLine()!;
        if (s == "#")
          break;
        var outArr = new char[s.Length];

        for (var i = 0; i < s.Length; i++) {
          var ch = s[i];
          var shift = i + 1;
          var upper = char.IsUpper(ch);
          var idxGroup = -1;
          var pos = -1;

          for (var g = 0; g < 8; g++) {
            var grp = upper ? up[g] : lo[g];
            var p = grp.IndexOf(ch);
            if (p != -1) {
              idxGroup = g;
              pos = p;
              break;
            }
          }

          var len = up[idxGroup].Length;
          var orig = (pos - shift) % len;
          if (orig < 0)
            orig += len;
          outArr[i] = upper ? up[idxGroup][orig] : lo[idxGroup][orig];
        }

        Console.WriteLine(new string(outArr));
      }
    }
  }
}

C++

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <bits/stdc++.h>
using namespace std;

typedef vector<string> vs;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  vs up = {"ABC", "DEF", "GHI", "JKL", "MNO", "PQRS", "TUV", "WXYZ"};
  vs lo = {"abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};

  string s;
  while (cin >> s) {
    if (s == "#")
      break;
    string out(s.size(), ' ');

    for (int i = 0; i < (int)s.size(); i++) {
      char ch = s[i];
      bool upper = isupper(ch);
      int shift = i + 1;
      int grpIdx = -1, pos = -1;

      for (int g = 0; g < 8; g++) {
        string& grp = upper ? up[g] : lo[g];
        int p = grp.find(ch);
        if (p != (int)string::npos) {
          grpIdx = g;
          pos = p;
          break;
        }
      }

      int len = (int)up[grpIdx].size();
      int orig = (pos - shift) % len;
      if (orig < 0)
        orig += len;
      out[i] = upper ? up[grpIdx][orig] : lo[grpIdx][orig];
    }

    cout << out << "\n";
  }

  return 0;
}