提交记录 #150
提交时间:2024-11-10 13:04:33
语言:c
状态:Unaccepted
编译情况:编译成功
固定测试点#1:
额外测试点#1:
38【日期】身份证的奥秘
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAX_LENGTH 20 // 身份证号码的最大长度
int weight[17] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
char checkCode[11] = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
// 判断身份证是否合法的函数
int isValidID18(const char *id18) {
int sum = 0;
// 计算加权和
for (int i = 0; i < 17; i++) {
if (!isdigit(id18[i])) {
return 0; // 非数字字符无效
}
sum += (id18[i] - '0') * weight[i];
}
// 计算校验码
int mod = sum % 11;
if (id18[17] != checkCode[mod]) {
return 0; // 校验码错误
}
return 1; // 身份证合法
}
// 将15位身份证号码升级到18位的函数
void upgradeTo18(const char *id15, char *id18) {
// 复制前6位地址码
strncpy(id18, id15, 6);
// 根据顺序码设置年份
if (id15[12] == '9' && (id15[13] == '9' || id15[13] == '6' || id15[13] == '7'
|| id15[13] == '8' || id15[13] == '0')) { // 999, 996, 997, 998, 999
id18[6] = '1'; // 年份前缀
id18[7] = '8'; // 设置为18yy
} else {
id18[6] = '1'; // 年份前缀
id18[7] = '9'; // 设置为19yy
}
// 复制出生日期部分
strncpy(id18 + 8, id15 + 6, 6); // 复制出生日期 (yyMMdd)
// 复制顺序码
strncpy(id18 + 14, id15 + 12, 3);
// 计算校验码
int sum = 0;
for (int i = 0; i < 17; i++) {
sum += (id18[i] - '0') * weight[i];
}
// 设置校验码
int mod = sum % 11;
id18[17] = checkCode[mod]; // 最后1位为校验码
// 设置结束符
id18[18] = '\0'; // 确保字符串结束
}
// 主函数
int main() {
int N;
scanf("%d", &N);
getchar(); // 读取换行符以避免影响后续 fgets 的读取
for (int i = 0; i < N; i++) {
char identity[MAX_LENGTH];
fgets(identity, sizeof(identity), stdin);
// 去掉可能的换行符
identity[strcspn(identity, "\n")] = '\0';
int length = strlen(identity);
if (length == 18) {
// 检查18位身份证号码的有效性
if (isValidID18(identity)) {
printf("Valid\n");
} else {
printf("Invalid\n");
}
} else if (length == 15) {
char id18[MAX_LENGTH];
upgradeTo18(identity, id18);
printf("%s\n", id18);
} else {
printf("Invalid\n");
}
}
return 0;
}