프로그래밍/알고리즘

BOJ 16196 · 중국 신분증 번호

반응형


알고리즘 분류 : 시뮬레이션, 문자열 처리  


문제를 천천히 정독하여 그대로 구현하면 된다. 날짜는 윤년도 고려해야 하므로, 윤달인 경우 29일이 될 수 있다.

문자열을 끊어서 읽은 후, 정수로 변환하여 유효성을 검사하면 된다.




C++ 소스코드


#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#define leapyear(y) (((y)%4==0)-((y)%100==0)+((y)%400==0)) 
using namespace std;

string id;
int n;
int days[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
vector<int> zone;

void solve() {
    int area = stoi(id.substr(0, 6));
    if (find(zone.begin(), zone.end(), area) == zone.end()) {
        cout << "I\n";
        return;
    }
    int year = stoi(id.substr(6, 4));
    if (year < 1900 || year > 2011) {
        cout << "I\n";
        return;
    }
    int month = stoi(id.substr(10, 2));
    if (month < 1 || month > 12) {
        cout << "I\n";
        return;
    }
    int day = stoi(id.substr(12, 2));
    if (day < 1) {
        cout << "I\n";
        return;
    }
    if (leapyear(year) && month == 2) {
        if (day > 29) {
            cout << "I\n";
            return;
        }
    } else {
        if (day > days[month]) {
            cout << "I\n";
            return;
        }
    }
    int order = stoi(id.substr(14, 3));
    if (order == 0) {
        cout << "I\n";
        return;
    }
    string x = id.substr(17, 1);
    int checksum;
    if (x == "X") checksum = 10;
    else checksum = stoi(x);
    for (int i=0; i<17; i++) {
        checksum += ((id[i]-'0')*(1<<(17-i)));
        checksum %= 11;
    }
    if (checksum != 1) {
        cout << "I\n";
        return;
    } else {
        if (order & 1) cout << "M\n";
        else cout << "F\n";
        return;
    }
}

int main() {
    ios_base::sync_with_stdio(false); cin.tie(NULL);
    cin >> id;
    cin >> n;
    for (int i=0; i<n; i++) {
        int z;
        cin >> z;
        zone.push_back(z);
    }
    solve();
    return 0;
}




Python 3 소스코드


from sys import stdin
input = stdin.readline

ids = input().strip()
zone = []
for _ in range(int(input())):
    zone.append(int(input()))
days = (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)

def leap(y):
    return (y%4 == 0) - (y%100 == 0) + (y%400 == 0)

def solve():
    area = int(ids[0:6])
    if area not in zone:
        print("I")
        return
    year = int(ids[6:10])
    if year < 1900 or year > 2011:
        print("I")
        return
    month = int(ids[10:12])
    if month < 1 or month > 12:
        print("I")
        return
    day = int(ids[12:14])
    if day < 1:
        print("I")
        return
    if leap(year) and month == 2:
        if day > 29:
            print("I")
            return
    else:
        if day > days[month]:
            print("I")
            return
    order = int(ids[14:17])
    if not order:
        print("I")
        return
    x = ids[17:18]
    if x == 'X':
        checksum = 10
    else:
        checksum = int(x)
    for i in range(17):
        checksum += (int(ids[i])*(1<<(17-i)))
        checksum %= 11
    if checksum != 1:
        print("I")
    else:
        if order & 1:
            print("M")
        else:
            print("F")

solve()




참고



반응형