[백준 6260] Encrypted SMS (C#, C++) - soo:bak
작성일 :
문제 링크
설명
휴대폰 멀티탭 입력에서 문자별 키와 눌림 횟수가 정해집니다. 키패드는 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;
}