3272: 公民身份号码
时间限制: 1 Sec 内存限制: 128 MB提交: 81 解决: 9
[ 提交][ 状态][ 讨论版]
题目描述
*居民身份证是国家法定的证明公民个人身份的有效证件。
公民身份号码是特征组合码,由17位数字本体码和1位数字校验码组成。排列顺序从左至右依次为:6位数字地址码,8位数字出生日期码,3位数字顺序码和1位数字校验码。
8位数字出生日期码,即公民身份号码的第7位到第14位,表示该居民出生的年、月、日,其中年份用4位数字表示,月和日分别用2位数字表示,且年、月、日之间不用分隔符。例如:2018年06月09日就用20180609表示。
3位数字顺序码中的最后一位,即公民身份号码的第17位,如果是奇数,表明该居民是男性;如果是偶数,表明该居民是女性。
最后1位数字校验码,即公民身份号码的第18位,计算方法如下:
(1)将前面的17位身份证号码分别乘以不同的系数。从第1位到第17位的系数分别为:7、9、10、5、8、4、2、1、6、3、7、9、10、5、8、4、2;
(2)将这17位数字和系数相乘之后的结果相加,再除以11;
(3)余数只可能是0、1、2、3、4、5、6、7、8、9、10这11个数字之一。其分别对应的最后一位身份证的号码为1、0、X、9、8、7、6、5、4、3、2。(即余数0对应1,余数1对应0,余数2对应X...)
给出一些不确定是否正确的18位公民身份号码,请你计算最后1位数字校验码是否正确。如果正确,输出公民身份号码对应居民的出生日期和性别;如果不正确,输出居民正确的公民身份号码(18位)、出生日期和性别。
输入
第一行输入测试数据的数目n;
第二行到第n+1行,每行输入一个不确定是否正确的18位公民身份号码。
输出
按照题意输出,个人信息之间用单个空格分隔开。
样例输入
2
370613199901101327
370613199810012450
样例输出
1999-1-10 female37061319981001245X 1998-10-1 male
提示
#include <stdio.h> #include <stdlib.h> int main() { int a[20],n,x[20]={0,7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2},sum=0,i; //使用数组保持系数 int judge[11]={0,1,2,3,4,5,6,7,8,9,10},year,moon,day; char c,s[11]={'1','0','X','9','8','7','6','5','4','3','2'}; scanf("%d",&n); while(n--) { sum=0; for(i=1;i<=17;i++) { scanf("%1d",&a[i]); sum+=a[i]*x[i]; } scanf("%c",&c); getchar(); sum%=11; for(i=0;i<12;i++) { if(sum==judge[i]) { break; } } if(c!=s[i]) { c=s[i]; for(i=1;i<=17;i++) printf("%d",a[i]); printf("%c ",c); } year=a[7]*1000+a[8]*100+a[9]*10+a[10]; moon=a[11]*10+a[12]; day=a[13]*10+a[14]; printf("%d-%d-%d ",year,moon,day); if(a[17]%2!=0) printf("male\n"); else printf("female\n"); } return 0; }