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

題目思路:本題與其他身份證號驗證的題目類似,但不同的是:

1.本題目中給定的身份證號不一定全爲數字還可能有字母X;

2.而且是加權求和得到sum;

3.最後他還要進行替換來實現對應比較。

經歷元氣滿滿的寫bug的過程之後的到以下代碼:

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n;
	cin>>n;
	//getchar();
	 int id[n];
	 for(int i=0;i<n;i++){
	 	id[i]=0;//初始化爲0,若爲1則輸出(有問題),0不輸出 (沒問題) 
	 } 
	getchar();
	char a[n][19];
	for(int i=0;i<n;i++){
	scanf("%s",a[i]);
	a[i][18]='\0';
	getchar();
	}
	char z;
	int sum=0;
	int t[17]={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
	
	for(int  i=0;i<n;i++){//檢查是否前十七位數字不爲字母 
		for(int k=0;k<17;k++){
			if(a[i][k]=='X'){
			id[i]=1;	//如果不符合,直接標記並跳出。
			break;		
			}
		
		}
		if(id[i]==0){//配合上面的跳出
		for(int l=0;l<17;l++){////使用一個數組來儲存 權重。
			sum+=t[l]*(a[i][l]-'0');//注意sum應該減去'0'!!!
		}
		z=sum%11+'0';
	//	printf("z is %c   ",z);
		if(z=='9'+1)z='2';
		else if(z=='2')z='X';
		else if(z=='1')z='0';
		else if(z=='0')z='1';
		else if(z=='3')z='9';
		else {
			z=12-(z-'0')+'0';//注意呀,找規律。。(不累的話也可以全部都寫一下替換2333333)
		}
		
		if(z!=a[i][17])id[i]=1;
	//	cout<<"id["<<i<<"]="<<id[i]<<"  "<<"a["<<i<<"][17]="<<a[i][17]<<"  "; ////檢測用的,因爲寫了好多bugbug
	//	printf("after  z==%c\n",z);
		sum=0;	
		}
		
	}
	//判斷輸出 
	int flag=0;
	for(int i=0;i<n;i++){
		if(id[i]==1){
		printf("%s\n",a[i]);
		flag=1;
		}
	}
	if(!flag)cout<<"All passed";
  
     return 0; 
}

希望能對你做題有所幫助,對於標準輸入輸出,pta不支持gets,哎。

發佈了24 篇原創文章 · 獲贊 7 · 訪問量 6828
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章