zoukankan      html  css  js  c++  java
  • [模拟]ZOJ3485 Identification Number

    题意:给了一串15位或18位的身份证号码,求 在改变最少位数的情况下, 输出正确合法的身份证号

    合法的身份证 是按照以下规则:

    前6位以及“Order code”三位  一定合法

    其中X是根据前17位的值计算出来的 按照如下公式  (a1就是最后一位,若为10就是X)

    另外 题目还规定了“Date of Birth” 要在1900.1.1到2011.4.2之间

    刚开始想这题的时候,觉得15位也就只需要 改变 年月日6位

                18位也就只需要 改变 年月日加X位9位而已

    但是打起来发现并非这么简单。。。

    单单是改变年月日就还需要考虑每月有多少天、需要考虑是否为闰年、需要考虑是否超过1900.1.1到2011.4.2的范围...

    对于18位的,改变了前面 还有影响到X的

    这样打下来相当之麻烦... 而且很容易错

    因此不能采用这种方法

    我们来换一种思路:

    假设, 我们已经知道了  “在改变最少位数之后的身份证号码”  那么来计算与输入的有几位不一样,那是一件很方便的事

    那么如何来得到 “在改变最少位数之后的身份证号码” 呢?

    我们只需要遍历1900.1.1到2011.4.1之间的每一天 (这样想之后, 发现给了一个范围真好啊!!)

    比较每一天与输入的需要改变几位,记录最小的 改变的位数 的那一天就好了

     1 string s;
     2 int run[2][12]={{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
     3                 {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
     4 
     5 int w[]={7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1};
     6 int a[20], b[20];
     7 int ans[25];
     8 void copy(int y, int m, int d)
     9 {
    10     for(int i=0; i<s.length(); i++)
    11         b[i]=a[i];
    12     if(s.length()==15)
    13     {
    14         b[6]=y%100/10, b[7]=y%100%10;
    15         b[8]=m/10, b[9]=m%10;
    16         b[10]=d/10, b[11]=d%10;
    17     }
    18     else
    19     {
    20         b[6]=y/1000, b[7]=y/100%10, b[8]=y%100/10, b[9]=y%100%10;
    21         b[10]=m/10, b[11]=m%10;
    22         b[12]=d/10, b[13]=d%10;
    23     }
    24 }
    25 int y, m, d;
    26 bool cao()
    27 {
    28     if(y==2011 && m==4 && d==2)
    29         return true;
    30     int Y=y, M=m, D=d+1;
    31     if(run[((Y%4==0 && Y%100) || Y%400==0)][M-1]+1==D)
    32         M++, D=1;
    33     if(M==13)
    34         Y++, M=1;
    35     copy(Y, M, D);
    36     y=Y, m=M, d=D;
    37     return false;
    38 }
    39 
    40 int main()
    41 {
    42     int t;
    43     scanf("%d", &t);
    44     while(t--)
    45     {
    46         cin>>s;
    47         for(int i=0;i<s.length();i++)
    48             a[i]=(s[i]=='X'? 10:s[i]-'0');
    49         y=1900, m=1, d=1;
    50         int minn=1000;
    51         copy(y, m, d);
    52         while(true)
    53         {
    54             int num=0;
    55             if(s.length()==18)
    56             {
    57                 int sum=0;
    58                 for(int i=0; i<17; i++)
    59                     sum+=b[i]*w[i];
    60                 b[17]=(12-sum%11)%11;
    61             }
    62             for(int i=0; i<s.length(); i++)
    63                 if(b[i]!=a[i])
    64                     num++;
    65             if(num<minn)
    66             {
    67                 for(int i=0; i<s.length(); i++)
    68                     ans[i]=b[i];
    69                 minn=num;
    70             }
    71             if(cao())
    72                 break;
    73         }
    74         for(int i=0; i<s.length(); i++)
    75         {
    76             if(ans[i]!=10)
    77                 printf("%d", ans[i]);
    78             else
    79                 putchar('X');
    80         }
    81         puts("");
    82     }
    83     return 0;
    84 }
    ZOJ 3485
  • 相关阅读:
    py笔记之循环结构
    PY学习记录#5
    PY学习记录#4
    py笔记之选择结构
    PY学习记录#3
    分享一个可以随时随地写代码的工具
    PY学习记录#2
    日记啊
    Tarjan学习笔记
    Docker commands
  • 原文地址:https://www.cnblogs.com/Empress/p/4391767.html
Copyright © 2011-2022 走看看