我纯暴力了, 没有任何的减枝。。。。 代码写得有点乱, 最后还是对拍出来了: 我天真以为月份是偶数的就是小月,奇的就是大月 = = #include <cstdio> #include <cstring> int s[19] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1}; int d[13] = {0, 31, 30, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; char num[24], ans[16], last; int min, pre, tail;; void gao1(int y, char *str){ for(int i = 1; i <= 12; i++) { int k; if(i == 2) { if(y == 0 || y%4 == 0) { k = 29; } else { k = 28; } } else { k = d[i]; } char tmp[6]; for(int j = 1; j <= k; j++) { sprintf(tmp, "%02d%02d", i, j); int diff = 0; for(int k = 0; k < 4; k++) { if(str[k] != tmp[k]) { diff++; } } if(diff < min) { min = diff; strcpy(ans, tmp); } } } } void gao2(char *str) { last = num[17]; for(int y = 1900; y <= 2011; y++) { int ml; if(y == 2011) { ml = 4; } else { ml = 12; } for(int i = 1; i <= ml; i++) { int k; if(i != 4) { if(i == 2) { if(y%4 == 0 && y != 1900) { k = 29; } else { k = 28; } } else { k = d[i]; } } else if(y == 2011){ k = 2; } else { k = 30; } char tmp[10]; for(int j = 1; j <= k; j++) { sprintf(tmp, "%d%02d%02d", y, i, j); int checkNum = pre+tail; for(int k = 0; k < 8; k++) { checkNum += (tmp[k]-'0')*s[k+6]; } checkNum = (12-checkNum%11)%11; if(checkNum == 10) { checkNum = 'X'; } else { checkNum += '0'; } int diff = 0; for(int k = 0; k < 8; k++) { if(str[k] != tmp[k]) { diff++; } } if(checkNum != num[17]) { diff++; } if(diff < min) { min = diff; strcpy(ans, tmp); last = checkNum; } } } } } int main(int argc, char* argv[]) { int T; scanf("%d", &T); getchar(); while(T--) { min = 20; gets(num); if(strlen(num) == 15) { gao1((num[6]-'0')*10+(num[7]-'0'),num+8); char* tp = num+8; for(int i = 0; i < 4; i++, tp++) { *tp = ans[i]; } printf("%s/n", num); } else { pre = 0; tail = 0; for(int k = 0; k < 6; k++) { pre += (num[k]-'0')*s[k]; } for(int k = 14; k < 17; k++) { tail += (num[k]-'0')*s[k]; } gao2(num+6); char *tp = num+6; for(int i = 0; i < 8; i++, tp++) { *tp = ans[i]; } num[17] = last; printf("%s/n", num); } } return 0; }