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 3
110105 320102
11010519491231002X
320102199502091613
110105198312310013

输出

Female
Male
Invalid

算法: 

无算法,模拟

预备知识(大佬略)

  •  字符串substr    截取字符串:s.substr(起始位置,截取长度)
  •  set查找元素     set.insert,set.count

 


 

正片

纯模拟

  1.  先判断前六位是否合法:可用set
  2. 再判断7~10的年份是否在1900~2011过了11年了
  3. 再判断月份以及对应天数是否符合  
    1. 如果年为闰年,则二月天数为29
    2. 月数是否在1~12之间
    3. 判断天数是否在每个月限定内 int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};    
      1. 判断天数是否为00,四十分就是这里错了
  4. 判断验证码是否为"000"
  5. 最后判断校验码
    1. 将21~217 与11的mod预处理出来
    2. 再将校验码加入扫一边即可

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 }
复制代码

 

 

 

                                      完结撒花

posted @   cym好名字  阅读(51)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示