题目编号:L1-016
分数:15分
语言:Java、Python
题目描述
身份证号码由17位数字和1位校验码组成。校验码可以是数字0-9,也可以是字符X。现在给定一些身份证号码,请你验证校验码的有效性,并输出有问题的号码。
输入格式
输入第一行给出正整数N(≤100),是输入的身份证号码的个数。随后N行,每行给出1个18位身份证号码。
输出格式
按照输入的顺序每行输出1个有问题的身份证号码。如果所有号码都正常,则输出 All passed。
输入样例
4
32012419880824156X
150404198708230612
120106197711022145
330702197712032113X
输出样例
150404198708230612
120106197711022145
解题思路
身份证校验码计算方法:前17位分别乘以对应系数并求和,结果对11取余得到余数,再通过余数表映射到校验码。
加权因子:{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}
校验码映射表:{'0':'1','1':'0','2':'X','3':'9','4':'8','5':'7','6':'6','7':'1','8':'0','9':'3','10':'2'}
关键点:
- 前17位必须全为数字
- 计算加权求和后取模11得到余数
- 将余数映射为校验码,与输入的第18位比对
- Python 中用字典做映射更简洁
代码实现
Java 实现
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int[] weight = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
char[] check = {'1', '0', 'X', '9', '8', '7', '6', '1', '0', '3', '2'};
int n = sc.nextInt();
boolean hasError = false;
for (int i = 0; i < n; i++) {
String id = sc.next();
boolean valid = true;
if (id.length() != 18) {
valid = false;
} else {
int sum = 0;
for (int j = 0; j < 17; j++) {
char c = id.charAt(j);
if (c < '0' || c > '9') {
valid = false;
break;
}
sum += (c - '0') * weight[j];
}
if (valid) {
char expect = check[sum % 11];
if (expect != id.charAt(17)) {
valid = false;
}
}
}
if (!valid) {
System.out.println(id);
hasError = true;
}
}
if (!hasError) {
System.out.println("All passed");
}
}
}
Python 实现
weight = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
check_map = ['1', '0', 'X', '9', '8', '7', '6', '1', '0', '3', '2']
n = int(input())
has_error = False
for _ in range(n):
id = input().strip()
valid = True
if len(id) != 18 or not id[:17].isdigit():
valid = False
else:
s = sum(int(id[j]) * weight[j] for j in range(17))
if check_map[s % 11] != id[17]:
valid = False
if not valid:
print(id)
has_error = True
if not has_error:
print("All passed")
运行验证
输入:
4
32012419880824156X
150404198708230612
120106197711022145
330702197712032113X
输出:
150404198708230612
120106197711022145
与样例一致,通过验证。
复杂度分析
- 时间复杂度:O(N × 17),N ≤ 100
- 空间复杂度:O(1)
总结
本题考察字符串处理和固定规则校验。核心是严格按照加权因子求和取模映射来验证校验码。注意第18位可以是数字或字符X。