『ACM C++』 PTA 天梯赛练习集L1 | 016-017
今天開了兩個大會,時間都給占掉了,就刷了兩道題~ 明天加油!!!
?
------------------------------------------------L1-016----------------------------------------------------------
查驗身份證
一個合法的身份證號碼由17位地區、日期編號和順序編號加1位校驗碼組成。校驗碼的計算規則如下:
首先對前17位數字加權求和,權重分配為:{7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};然后將計算的和對11取模得到值Z;最后按照以下關系對應Z值與校驗碼M的值:
Z:0 1 2 3 4 5 6 7 8 9 10 M:1 0 X 9 8 7 6 5 4 3 2現在給定一些身份證號碼,請你驗證校驗碼的有效性,并輸出有問題的號碼。
輸入格式:
輸入第一行給出正整數N(≤100)是輸入的身份證號碼的個數。隨后N行,每行給出1個18位身份證號碼。
輸出格式:
按照輸入的順序每行輸出1個有問題的身份證號碼。這里并不檢驗前17位是否合理,只檢查前17位是否全為數字且最后1位校驗碼計算準確。如果所有號碼都正常,則輸出All passed。
輸入樣例1:
4 320124198808240056 12010X198901011234 110108196711301866 37070419881216001X輸出樣例1:
12010X198901011234 110108196711301866 37070419881216001X輸入樣例2:
2 320124198808240056 110108196711301862輸出樣例2:
All passed------------------------------------------------L1-016----------------------------------------------------------
?注解:這題有點小難度,WA了幾次,但思路還是很清晰的,這道題需要注意以下幾點:
(1)注意scanf的輸入,他會吸換行,需要scanf(" %c",&id[j].number[i]);在%c前面補一個空格,表示吃掉換行。
即區分:scanf("%c",&answer) 與 scanf(" %c",&answer),后者只是在%前多了個空格,似乎沒有什么區別,但使用起來區別是很大的。
(2)注意對特殊元素‘X’符號的處理
· 代碼分塊:
第一步:構建基本變量參數:
int times,Z,num,count; float sum,T[17] = {7.0,9.0,10.0,5.0,8.0,4.0,2.0,1.0,6.0,3.0,7.0,9.0,10.0,5.0,8.0,4.0,2.0}; int check[11] = {1,0,40,9,8,7,6,5,4,3,2}; struct ID{char number[18];int illegal; }id[101];這里的T即為加權數,建議補.0,轉為浮點處理,以免后面除法出錯。check即為對應的驗證碼
然后這里我對ID的吸取利用了一個結構體,一個負責收數字信息,一個用來保存是否合法信息。
第二步:接受數據并進行預先求和處理
for(int i = 0;i<18;i++){scanf(" %c",&id[j].number[i]);num = id[j].number[i] - '0';if(0<=num && num<=9) sum+=(num*(T[i]));else{if(i != 17){id[j].illegal = 1;count++;}}}這里需要注意,如果前17位出現了X,那么這個身份證一定是不合法的,直接否掉就可以了。
第三步:驗證碼驗證最后一位數
if(id[j].illegal != 1){Z = int(sum)%11;if(num != check[Z]){id[j].illegal = 1;count++;}}這里需要注意下取模需要整數,因此需要轉換一下。
?
· AC代碼:
#include<stdio.h>int times,Z,num,count; float sum,T[17] = {7.0,9.0,10.0,5.0,8.0,4.0,2.0,1.0,6.0,3.0,7.0,9.0,10.0,5.0,8.0,4.0,2.0}; int check[11] = {1,0,40,9,8,7,6,5,4,3,2}; struct ID{char number[18];int illegal; }id[101]; int main() {scanf("%d ",×);count = 0;for(int j = 0;j<times;j++){sum = 0.0;for(int i = 0;i<18;i++){scanf(" %c",&id[j].number[i]);num = id[j].number[i] - '0';if(0<=num && num<=9) sum+=(num*(T[i]));else{if(i != 17){id[j].illegal = 1;count++;}}}if(id[j].illegal != 1){Z = int(sum)%11;if(num != check[Z]){id[j].illegal = 1;count++;}}}if(count == 0) printf("All passed\n");else for(int j = 0;j<times;j++) if(id[j].illegal == 1) puts(id[j].number);return 0; }?
·AC截圖:
?
?
?
?
------------------------------------------------L1-017----------------------------------------------------------
到底有多二
一個整數“犯二的程度”定義為該數字中包含2的個數與其位數的比值。如果這個數是負數,則程度增加0.5倍;如果還是個偶數,則再增加1倍。例如數字-13142223336是個11位數,其中有3個2,并且是負數,也是偶數,則它的犯二程度計算為:3/11×1.5×2×100%,約為81.82%。本題就請你計算一個給定整數到底有多二。
輸入格式:
輸入第一行給出一個不超過50位的整數N。
輸出格式:
在一行中輸出N犯二的程度,保留小數點后兩位。
輸入樣例:
-13142223336輸出樣例:
81.82%------------------------------------------------L1-017----------------------------------------------------------
注解:這題唯一新知識點就是對‘%’符號的輸出,若想輸出這個符號,在printf里面應該雙寫,即%%,即可出現%。
AC代碼:
#include<stdio.h> #include<string.h> char number[51]; int length,num2,shu; float fu,ou; int main() {scanf("%s",&number);fu = ou = 1;num2 = 0;length = strlen(number);for(int i = 0;i<length;i++){if(number[i] == '-') fu = 1.5;if(number[i] == '2') num2++;if(i == length - 1) if((number[i]-'0')%2 == 0) ou = 2.0;}if(fu == 1.5) printf("%.2f%%",(num2*fu*ou*100/(length-1)));else printf("%.2f%%",(num2*ou*100/(length)));return 0;}?
?
?
?
注:如果有更好的解法,真心希望您能夠評論留言貼上您的代碼呢~互相幫助互相鼓勵才能成長鴨~~
轉載于:https://www.cnblogs.com/winniy/p/10498836.html
總結
以上是生活随笔為你收集整理的『ACM C++』 PTA 天梯赛练习集L1 | 016-017的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 谈谈一些有趣的CSS题目(十七)-- 不
- 下一篇: vscode中go插件配置