ISBN(International Standard Book Number)은 전 세계 모든 도서에 부여된 고유번호로, 국제 표준 도서번호이다. ISBN에는 국가명, 발행자 등의 정보가 담겨 있으며 13자리의 숫자로 표시된다. 그중 마지막 숫자는 체크기호로 ISBN의 정확성 여부를 점검할 수 있는 숫자이다. 이 체크기호는 일련번호의 앞에서부터 각 자리마다 가중치 1, 3, 1, 3…. 를 곱한 것을 모두 더하고, 그 값을 10으로 나눈 나머지가 0이 되도록 만드는 숫자 m을 사용한다. 수학적으로는 다음과 같다.
ISBN이 abcdefghijklm 일 때, a+3b+c+3d+e+3f+g+3h+i+3j+k+3l+m ≡ 0 (mod 10)
즉, 체크기호 m = 10 - (a+3b+c+3d+e+3f+g+3h+i+3j+k+3l) mod 10 이다.
단, 10으로 나눈 나머지 값이 0일 경우 체크기호는 0이다.
전북대학교 중앙도서관에서 사서로 일하고 있는 영훈이는 책 정리를 하다가 개구쟁이 광현이에 의해서 ISBN이 훼손된 도서들을 발견했다. 광현이때문에 야근해야 하는 불쌍한 영훈이를 위해서 손상된 자리의 숫자를 찾아내는 프로그램을 작성해주자.
ISBN 13자리 숫자가 입력된다. 훼손된 숫자는 *로 표시한다. (훼손된 일련번호는 체크기호를 제외한 무작위 한 자리이다.)
우선, '*'을 거르며 input으로 받는 것을 구현 해야되며 받는 input이 character type이기 때문에 integer로 -'0'을 통하여 변환해주어야 된다. 그리고 모든 숫자의 패턴에 맞게 합을 구한 뒤 *자리만 for loop을 통해 1부터 9까지 넣어보면서 i를 식에 넣어서 맞는 i를 찾으면 그것을 출력 시키면 된다. 주의 해야 될 점은 짝수 번째면 3을 곱해야 된다는 것을 명심하고 case를 분리시켜서 관리하면 된다.
1부터 9까지의 값을 하나씩 넣어 보면서 맞는 답을 찾으면 그것을 출력하면 되는데 나는 그것을 생각 못하고수학적으로 접근하며 방정식을 풀듯이 문제를 풀려고 하여 생각 보다 오래 걸렸다.
#include <iostream>
using namespace std;
int main(void){
char numbersChar[14];
int erasedIndex, answer, sum = 0, numbersInt[14];
for(int i = 1; i < 14; i++){
cin >> numbersChar[i];
if(numbersChar[i] == '*'){
erasedIndex = i;
}
}
//숫자 input 변환 및 합 구하기
for(int i = 1; i < 14; i++){
if(i != erasedIndex){
//홀수
if(i%2==1){
numbersInt[i] = (int)numbersChar[i]-'0';
if(i==13){
break;
}
}
//짝수
else if(i%2==0){
numbersInt[i] = 3*((int)numbersChar[i]-'0');
}
}
else{
continue;
}
sum += numbersInt[i];
}
//알맞는 숫자 찾기
//홀수
if(erasedIndex%2==1){
for(int i = 0; i < 10; i++){
if((sum+i+numbersInt[13])%10==0){
answer = i;
}
}
}
//짝수
else if(erasedIndex%2==0){
for(int i = 0; i < 10; i++){
if((sum+3*i+numbersInt[13])%10==0){
answer = i;
}
}
}
cout << answer;
}