没想到的是直接枚举所有的年月日去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; }