CCF201812-3 CIDR合并 (python语言)

由于题目繁琐,本篇文章只解决题目中最简单的处理情况,可以得60分

试题编号:201812-3
试题名称:CIDR合并
时间限制:1.0s
内存限制:512.0MB
问题描述:



样例输入

2
1
2

样例输出

1.0.0.0/8
2.0.0.0/8

样例输入

2
10/9
10.128/9

样例输出

10.0.0.0/8

样例输入

2
0/1
128/1

样例输出

0.0.0.0/0

 

问题链接:CCF201812-3 CIDR合并

问题分析

这个题目实在是太长了。我花了大半天去读题也没有理解题目中的一些概念(ip前缀的匹配)所以做题时无从下手。

好在这道题最后说明了测试点的几种情况,所以我觉得觉得这道题目有困难的同学,可以用最少的时间拿分(把最简单的测试点通过),意思就是我们只处理第一个测试点(只需要完成排序操作)。下面分析怎么处理第一个测试点的情况:

首先,我们先明确要想通过测试点1需要怎样操作,大致可以分为以下几点:1.将输入格式化,题目中给出的输入可能缺少ip,也可能缺少前缀,也可能全部缺少,所以首先将输入格式化成标准形式。2.根据ip的大小进行排序。3.将ip值相同的元素根据前缀大小进行排序。4.输出结果。

我在下面代码中将这四个步骤分为两个函数去编写(ip_to_d是将ip地址转化为10进制以完成第一个排序),具体实现请阅读下面不是满分的代码。

60分代码

#将输入的数据预处理,变为合法的ip前缀表达式
def change_in(s):
    #找到‘/’位置和有几个‘.'
    position=0
    point=0
    for i in range(len(s)):
        if s[i]=='/':
            position=i
        if s[i]=='.':
            point+=1
    if position==0:
        position=len(s)
        s+=('/'+str(8+point*8))
    point=3-point
    #构造新的ip地址
    re=[]
    re+=[s[0:position]]
    for i in range(point):
        re[0]+=".0"
    #将ip地址和前缀大小分开,方便后面计算([1.1.1.1,/5])的形式
    re+=[int(s[position+1:])]
    return re
    
#将ip地址变为十进制数
def ip_to_d(s):
    num=[]
    befor=''
    for i in range(len(s[0])):
        if s[0][i]=='.':
            num+=[int(befor)]
            befor=''
        else:
            befor+=s[0][i]
    num+=[int(befor)]
    re_num=0
    for i in range(4):
        re_num+=(num[i]*(256**(3-i)))
    return re_num

#对s里面的ip地址进行排序
def ip_sort(s):
    t=[]
    for i in range(len(s)):
        t+=[[ip_to_d(s[i]),i]]
    #首先对ip地址的大小进行排序
    t.sort(key=lambda x:x[0])
    re=[]
    for i in range(len(s)):
        re+=[s[t[i][1]]]
    #其次对相同大小的ip地址进行前缀排序
    #将ip地址相同的元素依据前缀大小进行排序(为简单起见,用冒泡)
    for i in range(len(re)-1):
        for j in range(i+1,len(re)):
            if re[i][0]==re[j][0] :
                if re[i][1]>re[j][1]:
                    re[i],re[j]=re[j],re[i]
    return re

#程序执行
n=int(input())
s=[]
for i in range(n):
    s+=[input()]
for i in range(n):
    s[i]=change_in(s[i])
s=ip_sort(s)
for i in range(len(s)):
    print(s[i][0]+'/'+str(s[i][1]))

 

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值