Zerojudge a020

ZJ a020

題目

https://zerojudge.tw/ShowProblem?problemid=a020

給一個身分證字號,求是否符合身份證字號的規則,其規則如下:

  1. 先依照表格,將英文字母對應到數字
    1
    2
    3
    4
    5
    6
    7
    8
    9
    A=10 台北市     J=18 新竹縣     S=26 高雄縣
    B=11 台中市 K=19 苗栗縣 T=27 屏東縣
    C=12 基隆市 L=20 台中縣 U=28 花蓮縣
    D=13 台南市 M=21 南投縣 V=29 台東縣
    E=14 高雄市 N=22 彰化縣 W=32 金門縣
    F=15 台北縣 O=35 新竹市 X=30 澎湖縣
    G=16 宜蘭縣 P=23 雲林縣 Y=31 陽明山
    H=17 桃園縣 Q=24 嘉義縣 Z=33 連江縣
    I=34 嘉義市 R=25 台南縣
  2. 將第 1 步得到的數字的十位數以及個位數乘上 9 的值記錄下來為 $n$
  3. 數字從最左邊到最右邊依序乘上 8, 7, 6, … ,2, 1 ,並相加記錄下來為 $m$
  4. 若 $n+m$ 是 10 的倍數,表示正確,否則錯誤

若是正確的身分證輸出 real , 否則輸出 fake

想法

建立一個對照的表格(這裡以 function 實現),讓英文字能對應到相對的數字

接著做第 2 步驟,再判斷即可

建表稍微麻煩,但是只要用心就可以完成了

Code

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
#include<iostream> 
using namespace std;
string s;
int cnt=0,tmp;
int get_num(char c){
if(c>='A'&&c<='H')
return 10+(c-'A');
else if(c=='I')
return 34;
else if(c>='J' && c<='N')
return 18+(c-'J');
else if(c=='O')
return 35;
else if(c>='P' && c<='V')
return 23+(c-'P');
else if(c=='W')
return 32;
else if(c=='X')
return 30;
else if(c=='Y')
return 31;
else if(c=='Z')
return 33;
}
int main(){
cin>>s;
tmp=get_num(s[0]);
cnt+=(tmp/10)+(tmp%10)*9;
for(int i=1, T=8 ; i<s.size() ; i++,T--){
if(T==0)
cnt+=s[i]-'0';
cnt+=(s[i]-'0')*T;
}
if(cnt%10==0)
cout<<"real\n";
else
cout<<"fake\n";
return 0;
}

時間複雜度分析

由於字串的長度很小,並且每次計算的量值也很小,直接以 $O(1)$ 記之