ZOJ 3485 Identification Number【模拟】【暴力】

没想到的是直接枚举所有的年月日去count最小的作为答案,巧妙地解决了checksum的问题。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stdio.h>
#include<cmath>
#include<queue>
#include<map>
#include<iomanip> 
#include<algorithm>
#include<vector>
#define INF 2e9
#define maxnode 5000
using namespace std;

string s;
int w[20]={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2,1};      
int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};  

void solve15(){
    //前6个 与 后3个是什么都行
    int mi=INF,N;
    char pick[7];  
    for (int i=0;i<=99;i++){//枚举年 
        int run=(i%4==0);
        for (int j=1;j<=12;j++){//枚举月 
            int days;
            if(j==2) days=day[j]+run;
            else days=day[j];
            for (int k=1;k<=days;k++){//枚举日 
                char c[7];
                c[1]='0'+i/10;
                c[2]='0'+i%10;
                c[3]='0'+j/10;
                c[4]='0'+j%10;
                c[5]='0'+k/10;
                c[6]='0'+k%10;
                int cnt=0;  
                if (c[1]!=s[6]) cnt++;  
                if (c[2]!=s[7]) cnt++;  
                if (c[3]!=s[8]) cnt++;  
                if (c[4]!=s[9]) cnt++;  
                if (c[5]!=s[10]) cnt++;  
                if (c[6]!=s[11]) cnt++;  
                
                if (cnt<mi) { mi=cnt;  for(int i1=1;i1<=6;i1++) pick[i1]=c[i1];  }  
            }
        }
    } 
    for(int i=0;i<6;i++) cout<<s[i];  
    for(int i=1;i<=6;i++) cout<<pick[i];
    for(int i=12;i<15;i++) cout<<s[i];  
    cout<<endl;
}

void solve18(){
    //6-13 
    int mi=INF,num=0;  
    char last,pick[9];
    
    for(int i=0;i<=5;i++) num+=w[i]*( int(s[i])-48 ); 
    for(int i=14;i<=16;i++) num+=w[i]*( int(s[i])-48 );
    
    for (int i=1900;i<=2011;i++){
        for (int j=1;j<=12;j++){
            if(i==2011 && j>4) break;
            int days;
            if(j==2){
                if( (i%4==0&&i%100!=0 ) || i%400==0 ) days=29;
                else days=28;
            }
            else if( i==2011 && j==4 ) days=2;
            else days=day[j];//这一月有多少天 
            for (int k=1;k<=days;k++){
                char c[9];        
                c[1]= '0'+i/1000;
                c[2]= '0'+(i/100%10) ;
                c[3]= '0'+i/10%10 ;
                c[4]= '0'+i%10 ;
                c[5]= '0'+j/10 ;
                c[6]= '0'+j%10 ;
                c[7]= '0'+k/10 ;
                c[8]= '0'+k%10 ;
                int cnt=0;
                if (c[1]!=s[6]) cnt++;  
                if (c[2]!=s[7]) cnt++;  
                if (c[3]!=s[8]) cnt++;  
                if (c[4]!=s[9]) cnt++;  
                if (c[5]!=s[10]) cnt++;  
                if (c[6]!=s[11]) cnt++;  
                if (c[7]!=s[12]) cnt++;  
                if (c[8]!=s[13]) cnt++;  
                 
                 int n1=num;
                for(int i1=1;i1<=8;i1++) n1+=w[i1+5]*( int(c[i1])-48 );
                n1 = (12- (n1%11) )%11;
                
                if( n1==10 ){ if( s[17]!='X' ) cnt++; }
                else{ if( ( int(s[17])-48 ) !=n1 ) cnt++; }
                
                if( cnt<mi ){
                    mi=cnt; 
                    for(int i1=1;i1<=8;i1++) pick[i1]=c[i1];
                    if(n1==10) last='X';
                    else last='0'+n1;
                } 
            }  
        }  
    }  
   // cout<<"!!! "<<last<<endl;
    for (int i=0;i<6;i++) cout<<s[i];
    for(int i=1;i<=8;i++) cout<<pick[i];
    for (int i=14;i<17;i++) cout<<s[i];  
    cout<<last; 
    cout<<endl;
}

int main(){
//    cout<<'0'+5;
    int t; cin>>t;
    while(t--){
        cin>>s;
        if(s.length()==15) solve15();
        else solve18();
    }
    
    return 0;
}
原文地址:https://www.cnblogs.com/ZhenghangHu/p/9739044.html