문제 바로가기
접근 방법
- 문제가 어렵진 않지만 할 일이 많다.
- 56개의 숫자가 N번 반복되기 때문에 한 줄만 확인하면 된다.
- 그리고 암호코드의 규칙을 보면 모두 1로 끝난다.
- 그러면 마지막 1을 찾아서 그 앞으로 56개의 숫자를 찾아내면 되기 때문에 배열을 맨 뒤에서부터 확인하여 1의 위치를 찾는다.
- 그 위치부터 56개의 숫자를 찾아내어 역순을 해준다.
- 7개씩 잘라 각 암호에 맞는 숫자로 만들어 주면 된다.
풀이
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <cstdio>
using namespace std;
int tc, T, N, M, sum_code, last_i, last_j, odd, even, total_sum;
string scanner[] = { "0001101", "0011001", "0010011", "0111101", "0100011", "0110001",
"0101111", "0111011", "0110111", "0001011" };
vector<string> v;
string arr[56];
string passwordCode, realNumberCode;
void input() {
for (int i = 0; i < N; i++) {
cin >> arr[i];
}
}
void findLastOne() {
last_i = 0, last_j = 0;
for (int i = N - 1; i >= 0; i--) {
for (int j = M - 1; j >= 0; j--) {
if (arr[i][j] == "1"[0]) {
last_i = i;
last_j = j;
break;
}
}
if (last_i != 0)
break;
}
}
void findPasswordCode() {
passwordCode = "";
for (int i = last_i; i >= last_i; i--) {
for (int j = last_j; j > last_j - 56; j--) {
passwordCode += arr[i][j];
}
}
}
void splitPasswordCode() {
string temp = "";
for (int i = 0; i < passwordCode.size(); i++) {
if (temp.size() >= 7) {
v.push_back(temp);
temp = "";
}
temp += passwordCode[i];
}
v.push_back(temp);
}
void toRealCode() {
realNumberCode = "";
for (auto loop : v) {
for (int i = 0; i < 10; i++) {
if (loop == scanner[i]) {
realNumberCode += to_string(i);
}
}
}
}
void isRealCode() {
odd = 0, even = 0, total_sum = 0;
for (int i = 0; i < realNumberCode.size(); i++) {
if (i % 2 == 0) {
odd += realNumberCode[i] - '0';
}
else {
even += realNumberCode[i] - '0';
}
total_sum += realNumberCode[i] - '0';
}
}
void print() {
cout << "#" << tc << " ";
if ((3 * odd + even) % 10 == 0)
cout << total_sum << "\n";
else
cout << 0 << "\n";
}
int main() {
cin >> T;
for (tc = 1; tc <= T; tc++) {
cin >> N >> M;
input();
findLastOne();
findPasswordCode();
reverse(passwordCode.begin(), passwordCode.end());
splitPasswordCode();
toRealCode();
isRealCode();
print();
v.clear();
}
return 0;
}