Soulation to 身份证验证
https://www.luogu.com.cn/problem/T228160
题目描述
在中华人民共和国,每位公民都有一个唯一的身份证号码。中华人民共和国的居民身份证号码由 17 位本体码和 1 位校验码组成。17 位的本体码由三部分组成:地址码、出生日期码和顺序码。其中地址码占6 位、出生日期码占 8 位、顺序码占 3 位。顺序码的奇数分配给男性,偶数分配给女性,同时顺序码的 3 位不能为全 0。出生日期码的前 4 位表示出生年份,接下来 2 位表示出生月份,最后两位表示出生日期。考虑到实际的情况,我们约定出生日期必须在 1900 年 1 月 1 日到 2011 年 12 月 31 日的范围内,并且对于闰年1的 2 月有 29 日。最后对于地址码,它表示所属的行政区划,输入文件中会给出对于该测试点所有可行的地址码。1位的校验码是根据前面17 位计算得出的。将本体码从左到右用𝑎1, 𝑎2, … , 𝑎17表示,校验码用𝑥表示,则下面的关系成立:x+∑17i=1 *ai ≡ 1(mod 11)其中0 ≤ 𝑥 ≤ 10,如果𝑥 = 10,就用大写英文字母 X 表示。按照前面的规定,可以验证 11010519491231002X 是一个合法的女性身份证号码(110105 是北京市朝阳区的地址码)。现在要你写一个程序验证给定的身份证号码是否合法,并且对于合法的身份证,给出这位公民的性别。
输入格式
输入文件名为 verify.in,分为若干行。第一行包含两个正整数𝑀, 𝑁 (1 ≤ 𝑀 ≤ 4,000)。第二行包含𝑀个长度为 6 的数字串,表示该测试点中可行的地址码,地址码保证第一位数字非 0。下面包含𝑁行,每行给出一个长度为 18 的字符串,其中前 17 位为 0 到 9 的数字,第 18 位为 0 到 9 的数字或大写字母 X。
输出格式
输出文件名为 verify.out,共𝑁行,第𝑖行表示对于第𝑖个输入号码的判断结果。Invalid 表示不合法,Male 表示合法并且为男性,Female 表示合法并且为女性。
数据范围
(1 ≤ 𝑀 ≤ 4,000)。
样例 输入
2 3110105 32010211010519491231002X320102199502091613110105198312310013
输出
FemaleMaleInvalid
算法:
无算法,模拟
预备知识(大佬略)
- 字符串substr 截取字符串:s.substr(起始位置,截取长度)
- set查找元素 set.insert,set.count
正片
纯模拟
- 先判断前六位是否合法:可用set
- 再判断7~10的年份是否在1900~2011过了11年了
- 再判断月份以及对应天数是否符合
- 如果年为闰年,则二月天数为29
- 月数是否在1~12之间
- 判断天数是否在每个月限定内 int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
- 判断天数是否为00,四十分就是这里错了
- 判断验证码是否为"000"
- 最后判断校验码
- 将21~217 与11的mod预处理出来
- 再将校验码加入扫一边即可
C++代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 set<string> S; 4 int m,n; 5 string ans[100010]; 6 set<int > year; 7 int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; 8 int mi[18]={1,2,4,8,5,10,9,7,3,6,1,2,4,8,5,10,9,7}; 9 bool check(string s) 10 { 11 int len=s.size(); 12 int X; 13 if(s[17]=='X')X=10; 14 else X=s[17]-'0'; 15 int sum=X; 16 for(int i=0;i<=16;i++) 17 { 18 int nw=s[i]-'0'; 19 sum=sum+mi[17-i]*nw; 20 // cout<<sum<<' '; 21 } 22 // cout<<sum<<endl; 23 if(sum%11==1) 24 return true; 25 return false; 26 } 27 int main() 28 { 29 freopen("") 30 for(int i=1901;i<=2011;i++) 31 if(i%4==0) 32 year.insert(i); 33 cin>>m>>n; 34 while(m--) 35 { 36 char s[6]; 37 scanf("%s",s); 38 S.insert(s); 39 } 40 for(int i=1;i<=n;i++) 41 { 42 string s; 43 cin>>s; 44 string a=s.substr(0,6); 45 if(!S.count(a)) 46 { 47 ans[i]="Invalid"; 48 continue; 49 } 50 string b=s.substr(6,4); 51 int y=(b[0]-'0')*1000+(b[1]-'0')*100+(b[2]-'0')*10+b[3]-'0'; 52 if(y<1900||y>2011) 53 { 54 ans[i]="Invalid"; 55 continue; 56 } 57 string c=s.substr(10,2),d=s.substr(12,2); 58 int month=(c[0]-'0')*10+c[1]-'0'; 59 int da=(d[0]-'0')*10+d[1]-'0'; 60 if(month==0) 61 { 62 ans[i]="Invalid"; 63 continue; 64 } 65 if(month>13) 66 { 67 ans[i]="Invalid"; 68 continue; 69 } 70 if(month==2) 71 { 72 if(!year.count(y)) 73 { 74 if(day[month]<da) 75 { 76 ans[i]="Invalid"; 77 continue; 78 } 79 } 80 if(year.count(y)) 81 { 82 if(day[month]+1<da) 83 { 84 ans[i]="Invalid"; 85 continue; 86 } 87 } 88 } 89 else 90 { 91 if(day[month]<da) 92 { 93 ans[i]="Invalid"; 94 continue; 95 } 96 } 97 if(s.substr(14,3)=="000") 98 { 99 ans[i]="Invalid"; 100 continue; 101 } 102 if(check(s)==false) 103 { 104 ans[i]="Invalid"; 105 continue; 106 } 107 else 108 { 109 if((s[16]-'0')%2==1) 110 ans[i]="Male"; 111 else 112 ans[i]="Female"; 113 } 114 } 115 for(int i=1;i<=n;i++)cout<<ans[i]<<endl; 116 return 0; 117 }
完结撒花
英雄不问出路,流氓不看岁数!
分类:
szsy比赛
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】