Codebar 程式酒吧

一座輕鬆學習程式的酒吧

0%

a020. 身分證檢驗

題目連結

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

建議類題

a054. 電話客服中心

解題思路

本題的題意相當複雜,大致上的意思是:

  1. 讀取輸入的身分證字號。
  2. 將身分證字號中代表出生縣市的英文代號依照附圖的方式轉換成數字。
  3. 將2.的數字的個位數字乘以9倍並加上十位數字。
  4. 將身分證字號的數字部分由左到右分別乘上8、7、6、5、4、3、2、1、1。
  5. 以3.與4.的和做為判斷標準。若能被10整除則輸出”real”,否則輸出”fake”。

1.的部分需注意身份證字號的各數字之間沒有空格,若用整數型態的變數儲存會被讀取成一個整數。因此,這裡使用字元陣列讀取並儲存輸入的身分證字號。

2.就是單純的條件判斷,乍看之下需寫出26個英文字母各自的條件語句,但仔細觀察會發現有些英文字母的轉換是有規律的。我們可以善用這個規律化簡程式碼,將剛剛以字元型態讀取的英文代號先轉為ASCII碼,再經由加減運算得到如附圖中的數字。

3.的關鍵在於分別取得數字的個位數和十位數。個位數可以用除10後取餘數的方式獲得,而十位數則因為在整數型態的運算中,若運算結果為小數,會自動無條件捨去至整數位,剛好等於除10後的商。

4.的部分,可以看到前8位數字的倍數呈規律遞減,因此可善用for迴圈得出,第9位再單獨加上去就好了。

5.就是單純的條件判斷並輸出相對應的輸出!

注意事項

在進行資料型態的轉換時,會以「確保轉換過程中不會有資料遺失」為原則,因此若轉換後的資料型態所占的記憶體空間大於等於原資料型態,就可以直接轉換。以本題的程式碼來說,因為整數型態變數所佔的記憶體空間為4位元組,比字元型態變數所佔的1位元組還大,因此字元型態的變數在遇到需要用整數型態判別或運算的時候,會自動轉為整數,也就是其ASCII碼。嚴謹的寫法是 : (轉換後的的資料型態)變數名稱。 e.g. (int)city

程式碼:C語言

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
#include <stdio.h>
int main() {
//宣告並讀取字元型態變數city,代表身份證字號第一碼
//宣告並讀取字元陣列num,代表身分證字號後9碼
char city, num[10];
scanf("%c %s", &city, num);
//根據身份證字號第一碼所對應的出生城市,將其轉為數字
if(city >= 65 && city <= 72)
city-= 55;
else if(city == 'I')
city -= 39;
else if(city >= 74 && city <= 78)
city -= 56;
else if(city == 'O')
city -= 44;
else if(city >= 80 && city <= 86)
city -= 57;
else if(city == 'W')
city -= 55;
else if(city == 'X' || city == 'Y')
city -= 58;
else if(city == 'Z')
city -= 57;
//將轉換後得出的數字,個位數字乘以9倍並加上十位數字
int sum = city/10+(city%10)*9;
//將身分證字號的數字部分由左到右分別乘上8、7、6、5、4、3、2、1,最後再加上末碼
for(int i = 0 ; i < 8 ; i++)
sum += (num[i]-48)*(8-i);
sum += num[8]-48;
//若上述總和可被10整除就輸出real,否則輸出fake
if(sum%10 == 0)
printf("real");
else
printf("fake");

return 0;
}