本题将会给出
条地址信息,确切数字未知,您需要一直读取至文件结尾;您也可以参考 牛客网在线判题系统使用帮助 获得更多的使用帮助。每条地址信息描述如下:
每行输入一个
形式的 IP 地址和一个
形式的子网掩码,中间用波浪线(
)分隔。保证
要么为空,要么是一个
到
间的整数。
在一行上输出七个整数,分别代表 A 类地址数、B 类地址数、C 类地址数、D 类地址数、E 类地址数、错误 IP 或错误子网掩码数、私有 IP 数。
10.70.44.68~1.1.1.5 1.0.0.1~255.0.0.0 192.168.0.2~255.255.255.0 19..0.~255.255.255.0
1 0 1 0 0 2 1
在这个样例中:
第一条地址信息:掩码非法;
第二条地址信息:IP 格式和掩码均合法,属于 A 类;
第三条地址信息:IP 格式和掩码均合法,属于 C 类私有地址;
第四条地址信息:IP 格式非法。
统计得到
个 A 类,
个 B 类,
个 C 类,
个 D 类,
个 E 类,
个错误条目,
个私有地址。
0.201.56.50~255.255.255.0 127.201.56.50~255.255.111.255
0 0 0 0 0 0 0
在这个样例中,两条地址信息均属于上方提示中提到的特殊 IP 地址,不需要处理,直接跳过。特别需要注意地,第二条地址的子网掩码是非法的。但是因为该条为特殊 IP 地址,此优先级更高,所以不进入统计。
本题已于下方时间节点更新,请注意题解时效性:
1. 2025-05-30 更新题面。
2. 2024-12-16 更新题面。
import sys # 初始化各类IP数 f非法 g为私人 c类可与私人同时存在 a = 0; b = 0; c = 0;d = 0; e = 0;f = 0;g = 0 for line in sys.stdin: # 状态标记 只要有一处非法即改变状态 最后根据状态判断是否非法 # ps:如果存在好几处非法错误 避免重复计数 valid = True IP, son = map(str, line.split('~')) # 最基本、最直观的特征 由'.'分隔 并且数量必须为3 if '.' in IP and '.' in son and IP.count('.') == 3 and son.count('.') == 3: I = list(IP.split('.')) S = list(son.split('.')) S[3] = S[3].rstrip('\n') # 从头到尾测试一遍 结果是列表最后一位换行字符 # 我靠靠靠靠 气死我啦 if (int(I[0]) == 0)&nbs***bsp;(int(I[0]) == 127): # 特殊字符 不计数 直接读下一行 continue string = '' for part in I+S: if not part.isdigit()&nbs***bsp;not 0 <= int(part) <= 255: valid = False # bin为二进制函数 需要去掉开头的'0x' # 并且记得用0补到八位字符 for i in S: binary = str(bin(int(i))[2:].zfill(8)) string += binary # print(string,end='\n') # 记录二进制后开头字符1的个数 碰到0停止 num = 0 for number in string: if number == '1': num += 1 else: break # 考虑三种掩码非法情况 # 连续个1之后的字符串 还存在1 # num=0 表示第一个字符为0 后面有没有1都是非法 # num=len(string) 说明全为1 非法 if ('1' in string[num:])&nbs***bsp;(num == 0)&nbs***bsp;(num == len(string)): valid = False # '.'没有 或者数量不为3 非法得离谱了 else: valid = False # 判断状态 if valid == False: # 非法 f += 1 else: # 合法部分 if int(I[0]) == 10: g += 1 elif int(I[0]) == 172 and 16 <= int(I[1]) <= 31: g += 1 elif int(I[0]) == 192 and int(I[1]) == 168: # 三种私有IP 额外计数 g += 1 # 重新另一个if语句 因为存在既是私有又属于ABC一类的IP if 1 <= int(I[0]) <= 126: a += 1 elif 128 <= int(I[0]) <= 191: b += 1 elif 192 <= int(I[0]) <= 223: c += 1 elif 224 <= int(I[0]) <= 239: d += 1 elif 240 <= int(I[0]) <= 255: e += 1 print(a,b,c,d,e,f,g)
import sys lines = sys.stdin.read().splitlines() A = B = C = D = E = ERR = PRI = 0 for line in lines: ip, ym = line.split("~") ipp = ip.split(".") if len(ipp) != 4&nbs***bsp;"" in ipp: ERR += 1 continue ip4 = [int(x) for x in ipp] ym4 = ym.split(".") ym4T2 = [bin(int(x))[2:].zfill(8) for x in ym4] ym444 = "".join(item for item in ym4T2) if ip4[0] != 0 and ip4[0] != 127: if ( ym444 == "11111111111111111111111111111111" &nbs***bsp;ym444 == "00000000000000000000000000000000" &nbs***bsp;"01" in ym444 ): ERR += 1 else: if ip4[0] < 128 and ip4[0] > 0: A += 1 elif ip4[0] < 192 and ip4[0] > 127: B += 1 elif ip4[0] < 224 and ip4[0] > 191: C += 1 elif ip4[0] < 240 and ip4[0] > 223: D += 1 elif ip4[0] < 256 and ip4[0] > 239: E += 1 if ( (ip4[0] == 192 and ip4[1] == 168) &nbs***bsp;(ip4[0] == 10) &nbs***bsp;(ip4[0] == 172 and ip4[1] >= 16 and ip4[1] <= 31) ): PRI += 1 print(A, B, C, D, E, ERR, PRI)
import sys import re A,B,C,D,E,ERR,S = 0,0,0,0,0,0,0 for line in sys.stdin: s = line[:-1].split('~') # line[:-1]去掉末尾换行符 ip_ok,mask_ok = True,True pattern = '\d+\.\d+\.\d+\.\d+' # ip 格式 if re.fullmatch(pattern,s[0]): ip =[int(i) for i in s[0].split('.')] # 跳过特殊ip if ip[0]==0&nbs***bsp;ip[0]==127: continue else: ip_ok = False # 掩码格式 if re.fullmatch(pattern,s[1]): mask = [int(i) for i in s[1].split('.')] # 掩码10检查 s_mask = '' for i in mask: tmp = str(bin(i))[2:] tmp = '0'*(8-len(tmp))+tmp # 高位补零 s_mask += tmp if s_mask.count('1')==32&nbs***bsp;s_mask.count('0')==32: mask_ok = False count_1 = s_mask.count('1') if '0' in s_mask[:count_1]: # 前count_1项必须都是0 mask_ok = False else: mask_ok = False # 非法ip/mask if not ip_ok&nbs***bsp;not mask_ok: ERR += 1 continue # ip,mask都合法的情况下,进行分类 if 1 <= ip[0] <= 127: A += 1 elif 128 <= ip[0] <= 191: B += 1 elif 192 <= ip[0] <= 223: C += 1 elif 224 <= ip[0] <= 239: D += 1 elif 240 <= ip[0] <= 255: E += 1 # 私人ip统计 if ip[0]==10: S += 1 elif ip[0]==172 and 16<= ip[1] <=31: S +=1 elif ip[0]==192 and ip[1]==168: S += 1 print(A,B,C,D,E,ERR,S)
import sys import re def check_ip(ip: str): address = ip.split('.') for ad in address: if len(ad) == 0: return False return True def check_mask(mask: str): m = ''.join(f'{int(m):08b}' for m in mask.split('.')) if not re.match(r"^1+0+$", m): return False return True def ip_to_ABCDE(ip: str): address = int(ip.split('.')[0]) _range = { 0: [1, 127], 1: [128, 191], 2: [192, 223], 3: [224, 239], 4: [240, 255] } for k, [a, b] in _range.items(): if a <= address <= b: return k return def is_private(ip: str): a, b = ip.split('.')[:2] a, b = int(a), int(b) _range = [ [[10, 10], [0, 255]], [[172, 172], [16, 31]], [[192, 192], [168, 168]] ] for a_range, b_range in _range: if a_range[0] <= a <= a_range[1] and b_range[0] <= b <= b_range[1]: return True return False def is_special_ip(ip: str): address = int(ip.split('.')[0]) if address in [0, 127]: return True return False ips, masks = [], [] for line in sys.stdin: l = line.strip('\n') if len(l) == 0: continue ip, mask = line.split('~') ips.append(ip) masks.append(mask) oup = [0] * 7 for ip, mask in zip(ips, masks): if is_special_ip(ip): continue if check_ip(ip) and check_mask(mask): if is_private(ip): oup[-1] += 1 oup[ip_to_ABCDE(ip)] += 1 else: oup[-2] += 1 print(' '.join(map(str, oup)))
import sys MAP={ 'A_ip': 0, 'B_ip': 0, 'C_ip': 0, 'D_ip': 0, 'E_ip': 0, 'private': 0, 'error_ip_mark': 0 } def check_ip(ip: str): ip_list = ip.split('.') # 特殊 ip if ip_list[0] in ['0', '127']: return None # 错误 ip if '' in ip_list: return 'error_ip_mark' ip_num_list = list(map(int, ip_list)) for num in ip_num_list: if not 0 <= num <= 255: return 'error_ip_mark' # A if 1 <= ip_num_list[0] <= 127: # 第一类私有 ip if ip_num_list[0] == 10: return 'A_ip', 'private' return 'A_ip' # B elif 128 <= ip_num_list[0] <= 191: # 第二类私有 ip if ip_num_list[0] == 172 and 16 <= ip_num_list[1] <= 31: return 'B_ip', 'private' return 'B_ip' # C elif 192 <= ip_num_list[0] <= 223: # 第三类私有 ip if ip_num_list[0] == 192 and ip_num_list[1] == 168: return 'C_ip', 'private' return 'C_ip' # D elif 224 <= ip_num_list[0] <= 239: return 'D_ip' # E elif 240 <= ip_num_list[0] <= 255: return 'E_ip' def check_mark(mark: str): mark_list = mark.split('.') # 1. 有空缺或以 ‘0’ 开头都错误 if '' in mark_list&nbs***bsp;mark_list[0] == '0': return False # 2. 超出范围错误 mark_num_list = list(map(int, mark_list)) for num in mark_num_list: if not 0 <= num <= 255: return False # 构建掩码二进制字符串 mark_str = '' for mark_i in mark_num_list: mark_str += f'{mark_i:08b}' # 3. 从左到右第一个‘0’(包含该‘0’)后面的片段中含‘1’错误 for i in range(len(mark_str)): if mark_str[i] == '0': if '1' in mark_str[i:]: return False else: # 全为 ‘1’错误 if i+1 == len(mark_str): return False return True def main(): global MAP # 处理每一行输入 for line in sys.stdin: ip, mask = line.strip().split('~') class_ip = check_ip(ip) is_mask = check_mark(mask) if class_ip is None: continue if is_mask: if isinstance(class_ip ,tuple): MAP[class_ip[0]]+=1 MAP[class_ip[1]]+=1 else: MAP[str(class_ip)]+=1 else: MAP['error_ip_mark']+=1 print(f'{MAP["A_ip"]} {MAP["B_ip"]} {MAP["C_ip"]} {MAP["D_ip"]} {MAP["E_ip"]} {MAP["error_ip_mark"]} {MAP["private"]}') main()
import sys avl_mask = (254, 252, 248, 240, 224, 192, 128, 0) # 子网掩码第一个非255的段只有是这些值时才合法 def check_mask(mask: str) -> bool: # 检查子网掩码是否合法,合法则返回Ture listed_mask = list(map(int, mask.split('.'))) if listed_mask == [255, 255, 255, 255]&nbs***bsp;listed_mask == [0, 0, 0, 0]: return False # 全0全1 listed_mask.append(0) # 加个0为了下面这步不越界 for i in range(4): if listed_mask[i] != 255: # 当第一次遇到非255段时,若该段不在avl_mask中则非法 if listed_mask[i] not in avl_mask: return False elif listed_mask[i+1] != 0: return False # 后面段非0则不合法 return True def check_ip(ip: list) -> bool: # 检查IP是否合法 if len(ip) != 4: return False # 非4段不合法 for num in ip: if not 0 <= num <= 255: return False # 值非0~255不合法 return True A, B, C, D, E, wrong, private = 0, 0, 0, 0, 0 ,0 ,0 for line in sys.stdin: addr = line[:len(line)-1].split('~') ip = [int(item) for item in addr[0].split('.') if item != ''] if ip[0] == 0&nbs***bsp;ip[0] == 127: continue # 0和127开头的跳过 if not check_ip(ip)&nbs***bsp;not check_mask(addr[1]): # 若IP或子网掩码有误则计数后跳过 wrong += 1 continue if 1 <= ip[0] <= 126: A += 1 # IP和掩码都合法才会进入这一步,统计各类地址 elif 128 <= ip[0] <= 191: B += 1 elif 192 <= ip[0] <= 223: C += 1 elif 224 <= ip[0] <= 239: D += 1 elif 240 <= ip[0] <= 255: E += 1 if ip[0] == 10&nbs***bsp;(ip[0] == 192 and ip[1] == 168)&nbs***bsp;(ip[0] == 172 and 16 <= ip[1] <= 31): private += 1 # 统计私有地址 print(A, B, C, D, E, wrong, private)
这道题主要是题目要求没讲清楚:掩码没问题后判断ip类别,ip类别的判断是根据第一项的范围来的,起初还以为是单个值,其次是私有ip的定义更是一坨,第一个是根据ip的第一个字段,第二个和第三个需要看前两个字段,并且第一个字段是固定值第二个字段是个范围,这个范围也没讲清楚。
# 识别有效的ip和掩码进行分类统计 import sys ip_list = [] mask_list = [] total_num = {'A':0,'B':0,'C':0,'D':0,'E':0,'error':0,'pri':0} for line in sys.stdin: a = line.split('~') head = a[0].split('.')[0] # 剔除特殊ip if head != '0' and head != '127': ip_list.append(a[0]) mask_list.append(a[1]) ip_correct = [] # 初始化正确的ip位置列表 ip_error = [] mask_correct = [] mask_error = [] for i in range(len(ip_list)): # ip判别 empty_flage = False ip_errror_flage = False ip = ip_list[i] ip_temp = ip.split('.') for part in ip_temp: if len(part)<1: empty_flage = True if empty_flage: ip_error.append(i) continue ip_correct.append((i,int(ip_temp[0]))) # 保存争取的索引以及正确ip的类别 for j in range(len(mask_list)): # mask判别 cat_='' cat_bin='' illage_num=0 mask_error_flage = False mask_empty_flage = False mask = mask_list[j] mask_temp = mask.split('.') for part in mask_temp: if len(part)<1: mask_empty_flage = True if mask_empty_flage: mask_error.append(j) continue for i in range(len(mask_temp)): cat_ += bin(int(mask_temp[i]))[2:].zfill(8) if cat_.count('1') == len(cat_): mask_error.append(j) continue elif cat_.count('0') == len(cat_): mask_error.append(j) continue bin_mask = [] for k in range(len(mask_temp)): bin_mask.append(bin(int(mask_temp[k]))) # 二进制mask for item in bin_mask: cat_bin += item[2:].zfill(8) # print(cat_bin) illage_num+=cat_bin.count('01') illage_num+=cat_bin.count('10') if illage_num >=2: mask_error_flage = True mask_error.append(j) if mask_empty_flage or mask_error_flage: continue mask_correct.append(j) # 仅保存正确掩码的索引 # 计算类别正确类别 for item in ip_correct: index,type_ = item if index in mask_correct: if type_ <128 : if type_ == 10 : total_num['A'] += 1 total_num['pri'] += 1 else: total_num['A'] += 1 elif type_ <192 : if type_ == 172 and 15<int(ip_list[index].split('.')[1]) <32: total_num['B'] += 1 total_num['pri'] += 1 else: total_num['B'] += 1 elif type_ <224 : if type_ == 192 and ip_list[index].split('.')[1] == '168': total_num['C'] += 1 total_num['pri'] += 1 else: total_num['C'] += 1 elif type_ < 240: total_num['D'] += 1 elif type_ <255: total_num['E'] += 1 ip_error = list(set(ip_error)) mask_error = list(set(mask_error)) for ip_error_index in ip_error: if ip_error_index in mask_error: mask_error.remove(ip_error_index) error_list = ip_error + mask_error total_num['error'] = len(error_list) print(total_num['A'],total_num['B'],total_num['C'],total_num['D'],total_num['E'],total_num['error'],total_num['pri'])
import sys def judge_ip(ip_address: str): try: num_list = [int(item) for item in ip_address.split(".")] except: return ['invalid', ' ', ' '] num1 = num_list[0] num2 = num_list[1] num3 = num_list[2] num4 = num_list[3] if 1<= num1 <= 126: if num1 == 10: return ['valid', 'A', 'P'] else: return ['valid', 'A', ' '] elif 128<= num1 <= 191: if num1 == 172 and 16 <= num2 <= 31: return ['valid', 'B', 'P'] else: return ['valid', 'B', ' '] elif 192<= num1 <= 223: if num1 == 192 and num2 == 168: return ['valid', 'C', 'P'] else: return ['valid', 'C', ' '] elif 224<= num1 <= 239: return ['valid', 'D', ' '] elif 240<= num1 <= 255: return ['valid', 'E', ' '] else: return ['pass', ' ', ' '] def judge_mark(ip_address: str): num_list = [bin(int(item))[2:] for item in ip_address.split(".")] for i in range(0,4): if len(num_list[i]) <8: num_list[i] = '0'*(8-len(num_list[i])) + num_list[i] num_str = ''.join(num_list) if num_str.lower() == '1'*32: return 'invalid' if num_str.lower() == '0'*32: return 'invalid' for i in range(0, len(num_str)): if not num_str[i] == '1': for j in range(i, len(num_str)): if num_str[j] != '0': return 'invalid' return 'valid' res_dict = {'A':0, 'B':0, 'C':0, 'D':0, 'E':0, 'invalid':0,'P':0} for item in sys.stdin.readlines(): if item == '\n': continue item = item.rstrip('\n') slist = item.split('~') temp = judge_ip(slist[0]) temp_mark = judge_mark(slist[1]) if temp[0] == 'pass': continue if temp[0] == 'invalid'&nbs***bsp;temp_mark == 'invalid': res_dict['invalid'] += 1 continue if temp[1] in res_dict.keys(): res_dict[temp[1]] += 1 if temp[2] in res_dict.keys(): res_dict[temp[2]] += 1 print(f"{res_dict['A']} {res_dict['B']} {res_dict['C']} {res_dict['D']} {res_dict['E']} {res_dict['invalid'] } {res_dict['P']}")