一个合法的身份证号码由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
!!!!!!!这里给大家解释一下什么是加权求和?
加权:每个身份证数字与对应位置的权重的乘积。例如身份证号码320124198808240056,权重分配为:{7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2},第一次加权就为3 * 7,第二次2 * 9,以此类推。
加权求和当然就是所有加权过的数字之和(如3 * 7+2 * 9+.....+)了,这里需注意是身份证前17位数加权求和后对11取模(求余)判断与第十八位校验码是否相等。
C++:
#include<iostream> using namespace std; int main() { int a[]={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2}; //题目所给的权重分配 char c[]={'1','0','X','9','8','7','6','5','4','3','2'};//权重求和取模后所对应的校验码 int n; cin>>n; int sum=0; int judge=0; //用来判断所给身份证是否有问题 0表示为没有问题 1表示为有问题 string s; for(int i=1;i<=n;i++) { cin>>s; //这里没有涉及输入空格所以用cin直接输入即可 sum=0; //权重之和 for(int j=0;j<17;j++) //遍历身份证前十七位数字 { if(s[j]=='X') //如果出现非数字即身份证有问题 { cout<<s<<endl; //直接输出 judge=1; //然后判断标记为1(有问题) break; } else { sum+=( (s[j]-'0') *a[j]); //否则的话就加权这个数字 } } if(c[sum%11]!=s[17]) //判断加权求和取模后对应的校验码是否等于最后一位 { cout<<s<<endl; //如果不是即身份证有问题,输出即可 judge=1; //判断标记 } } if(judge==0) //所有输入完成后若标记还是为0即所有身份证都没有问题 cout<<"All passed"; //输出All passed }
使用二维数组和计数法也可以解决这题(建议思考一个问题从多个角度和方向解决)
C语言:
#include<stdio.h> int main() { int n,sum,count=0,judge; //count表示身份证有问题的数量 int a[]={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2}; char c[]={'1','0','X','9','8','7','6','5','4','3','2'}; char num[101][101]; //二维字符数组来输入 scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%s",&num[i]); } for(int i=1;i<=n;i++) { sum=0; //权重之和 judge=0; for(int k=0;k<17;k++) { if(num[i][k]=='X') judge=1; //判断身份证是否有问题 1为有问题 0为没有问题 else sum+=(num[i][k] - '0') * a[k]; //加每个符合条件加权后的数 } if(c[sum%11] != num[i][17]) //判断加权求和取模后对应的校验码是否等于最后一位 judge=1; if(judge == 1) { printf("%s\n",num[i]); count++; //每输出一串有问题的身份证号码count就自增1 } } if(count == 0) //count为0即没有有问题的身份证号码 printf("All passed"); return 0; }