#include <stdio.h>
char code[2000][501];
int password[8];
int bin[2000];
int decode(int);
int main()
{
freopen("input.txt", "r", stdin);
int T, test_case;
int N, M;
int odd, even;
int res;
int tmp;
int ratio[3];
int length;
int end;
int i, j, k, l;
scanf("%d", &test_case);
for (T = 1; T <= test_case; ++T)
{
res = 0;
scanf("%d %d", &N, &M);
for (i = 0; i < N; ++i)
scanf("%s", *(code + i));
for (i = 0; i < N; ++i)
{
for (j = M - 1; j >= 0; --j)
{
if (code[i][j] != '0')
{
ratio[0] = ratio[1] = ratio[2] = 0;
length = 100;
for (k = 0; k < 8; ++k)
password[k] = 0;
odd = even = 0;
for (k = j; k >= 0; --k)
{
if (code[i][k] >= 'A')
tmp = code[i][k] - 'A' + 10;
else if (code[i][k] >= '0')
tmp = code[i][k] - '0';
for (l = 0; l < 4; ++l)
{
bin[4 * (j - k) + l] = tmp % 2;
tmp /= 2;
}
}
k = 0;
while (bin[k] == 0)
++k;
for (l = 0; l < 3; ++l) // 최소 연속된 숫자를 찾는 것임
{
while (bin[k] == (l + 1) % 2)
{
++k;
ratio[l]++;
}
if (length > ratio[l])
length = ratio[l];
}
tmp = j - length * 14;
end = (tmp > 0 ? tmp : 0);
tmp = 0;
while (bin[tmp] == 0)
++tmp;
for (k = 7; k >= 0; --k)
{
for (l = 0; l <= 6; ++l, tmp += length)
password[k] += (bin[tmp] << l);
password[k] = decode(password[k]);
if ((k + 1) % 2)
odd += password[k];
else
even += password[k];
}
if ((3 * odd + even) % 10 == 0)
res += (odd + even);
for (k = i; code[k][(end + j) / 2] != '0'; ++k) // 16진수가 붙어 있으므로, 가운데에 0이 들어갈 수 없음
{
for (l = end; l <= j; ++l)
code[k][l] = '0';
}
}
}
}
printf("#%d %d\n", T, res);
}
return 0;
}
int decode(int src)
{
switch (src)
{
case 13: return 0;
case 25: return 1;
case 19: return 2;
case 61: return 3;
case 35: return 4;
case 49: return 5;
case 47: return 6;
case 59: return 7;
case 55: return 8;
case 11: return 9;
default: return -1;
}
}
댓글