CCF 201812-3 CIDR合并
CCF 201812-3 CIDR合并

//100分 93ms
#include<stdio.h>//CCF上stdio.h比cstdio快!!!
#include<string.h>
#include<algorithm>
typedef unsigned int UI;
const int N=1e5+;
struct IP{UI val,a[];}ip[N];//a[0]~a[3]表示IP地址,a[4]表示题目中的len
//val表示IP地址的十进制形式(主要作用:IP前缀能表示的数值范围)
char str[];int n;
void dealStr(int id){//字符串点分数字,转换成标准型
scanf("%s",str);
int cnt(),pn(),xn(),len=strlen(str);//pn点的数量,sn斜杠的数量
for(int i=;i<len;i++){
if(str[i]=='.') pn++;else
if(str[i]=='/') xn++;
}
for(int i=;i<;i++) ip[id].a[i]=;
char *p1=str,*p2,tmp[];
for(int i=;i<pn;i++){
p2=strchr(p1,'.');
strncpy(tmp,p1,p2-p1);//strncpy复制从p1中p2-p1长度的字符串到tmp中
tmp[p2-p1]=;
ip[id].a[cnt++]=atoi(tmp);
p1=p2+;
}
if(xn){
p2=strchr(p1,'/');//strchr从p1中查找‘/’第一次出现的位置
strncpy(tmp,p1,p2-p1);
tmp[p2-p1]=;
ip[id].a[cnt++]=atoi(tmp);//atoi 字符串转数字
p1=p2+;
strcpy(tmp,p1);
ip[id].a[]=atoi(tmp);
}
else{
strcpy(tmp,p1);
ip[id].a[cnt++]=atoi(tmp);
ip[id].a[]=cnt*;
}
ip[id].val=;//计算ip十进制值
for(int i=;i<;i++) ip[id].val+=ip[id].a[i]<<*(-i);
}
inline bool cmp(const IP &ip1, const IP &ip2){
for(int i=;i<;i++) if(ip1.a[i]!=ip2.a[i]) return ip1.a[i]<ip2.a[i];
return ;
}
inline void range(IP &ip0,UI &l,UI &r){//计算IP前缀能表示的数值范围
UI len=-ip0.a[];
l=ip0.val>>len<<len;
r=ip0.val|((<<len)-);
}
void union1(){//从小到大合并
int p=;
UI la,lb,ra,rb;
for(int i=;i<n;i++){
range(ip[p],la,ra);
range(ip[i],lb,rb);
if(la>lb||rb>ra) ip[++p]=ip[i];
}
n=p+;
}
inline bool judgeUnion(IP &ip1,IP &ip2,IP &res){//判断同级能否合并
if(ip1.a[]!=ip2.a[]||ip1.a[]<) return ;
res=ip1;res.a[]--;
UI la,lb,lc,ra,rb,rc;
range(ip1,la,ra);
range(ip2,lb,rb);
range(res,lc,rc);
if(la==lc&&rb==rc&&lb<=ra+) return ;
return ;
}
void union2(){
int p=;IP res;
for(int i=;i<n;i++){
if(judgeUnion(ip[p],ip[i],res)){
ip[p]=res;
while(p>&&judgeUnion(ip[p-],ip[p],res)) ip[--p]=res;
}
else{
ip[++p]=ip[i];
}
}
n=p+;
}
int main(){
scanf("%d",&n);
for(int i=;i<n;i++) dealStr(i);
std::sort(ip,ip+n,cmp);
union1();
union2();
for(int i=;i<n;i++) printf("%u.%u.%u.%u/%u\n",ip[i].a[],ip[i].a[],ip[i].a[],ip[i].a[],ip[i].a[]);
return ;
}
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + ;
struct node {
int ip[] , len , ip4[];
unsigned int d;
node(string s) {
bool flag = ;
int cnt = ;
d = len = ;
memset(ip,,sizeof(ip));
for(int i = ; i < s.length() ; i++) {
if(s[i] == '.')continue;
else if(s[i] == '/') {
flag = ;continue;
}
else {
int t = ;
while(isdigit(s[i])) {
t = t * + s[i] - '';
i++;
}
i--;
if(!flag)ip[cnt++] = t;
else len = t;
}
}
if(!len)len = cnt * ;
cnt = ;
for(int i = ; i < ; i++) {
d = d * + ip[i];
int t = ip[i];
for(int j = cnt ; j >= cnt - ; j--) {
ip4[j] = t % ;
t /= ;
}
cnt += ;
}
}
node(){}
bool operator < (const node b) const {
return d < b.d || (d == b.d && len < b.len);
}
};
node a[maxn];
list<node> ans;
bool vis[maxn];
bool judge(node b , node c) {
if(c.len < b.len)return false;
for(int i = ; i < b.len ; i++) {
if(b.ip4[i] != c.ip4[i]) {
return false;
}
}
return true;
}
bool judge1(node b , node c) {
if(c.len != b.len || c.len == )return false;
for(int i = ; i < b.len - ; i++) {
if(b.ip4[i] != c.ip4[i])return false;
}
int len = b.len - ;
if(b.ip4[len] != c.ip4[len]) return true;
else return false;
}
int main() {
int n;
ios::sync_with_stdio();
cin.tie();cout.tie();
cin >> n;
for(int i = ; i < n ; i++) {
string s;
cin >> s;
a[i] = node(s);
}
sort(a , a + n);
for(int i = ; i < n ; ) {
int p = i;
i++;
while(i < n && !vis[i]) {
if(judge(a[p] , a[i])) {
vis[i] = ;
i++;
}
else break;
}
}
for(int i = ; i < n ; i++) {
if(!vis[i])ans.push_back(a[i]);
}
for(auto t = ans.begin() ; t != ans.end() ; t++) {
auto t1 = t;
t1++;
while(t1 != ans.end() ) {
if(judge1(*t , *t1)) {
t -> len = t -> len - ;
ans.erase(t1);
if(t != ans.begin())t--;
t1 = t; t1++;
}
else break;
}
}
for(auto t = ans.begin() ; t != ans.end() ; t++) {
cout << t -> ip[] << "."<< t -> ip[] << "." << t -> ip[] << "." << t -> ip[] << "/" << t -> len<< "\n";
}
return ;
}
网上list版代码
CCF 201812-3 CIDR合并的更多相关文章
- CCF201812-3 CIDR合并
按题意模拟即可...主要CCF吞代码... #include<bits/stdc++.h> #define pb push_back #define mp make_pair #defin ...
- CIDR合并
code #include <iostream> #include <list> #include <sstream> #include <vector> ...
- CCF-CSP题解 201812-3 CIDR合并
题目想求与给定前缀列表等价的包含IP前缀数目最少的前缀列表. 首先是怎么存储前缀列表.用一个long long存储IP地址,再存一个前缀长度,封装在一个结构体里\(<ipNum, len> ...
- CCF-CSP认证 C++题解目录
持续更新中,记录刷题过程并分享一下小小的心得总结. 试题编号 试题名称 标签 202006-1 线性分类器 | 题解 线性规划 202006-2 稀疏向量| 题解 归并排序思想 202006-3 化学 ...
- CIDR
CIDR的介绍: CIDR(Classless Inter-Domain Routing,无类域间路由选择)它消除了传统的A类.B类和C类地址以及划分子网的概念,因而可以更加有效地分配IPv4的地址空 ...
- 无分类编址(CIDR)构成超网
CIDR(无分类域间路由选择) CIDR最主要有两个以下特点: 消除传统的A,B,C地址和划分子网的概念,更有效的分配IPv4的地址空间,CIDR使IP地址又回到无分类的两级编码.记法:IP地址::= ...
- 第5章 子网划分和CIDR
第5章 子网划分和CIDR 划分网络 根据A类.B类或C类网络ID来识别网段具有一些局限性,主要是在网络级别之下不能对地址空间进行任何逻辑细分 如果一个IP是一个A类网络.数据报到达网关,然后传输到9 ...
- 无分类编址(CIDR,Class Inter-Domain-Routing)
CIDR全称是无分类域间路由选择,英文全称是Classless Inter-Domain Routing,大家多称之为无分类编址 CIDR的特点 (1)CIDR消除了传统的A类.B类和C类地址以及划分 ...
- IP地址和CIDR
IP地址(IPV4) IPV4的地址是一个32位的二进制数,由网络ID和主机ID两部分组成,用来在网络中唯一的标识一台计算机.IP地址通常用四组3位的十进制数表示,中间用.分割,例如:192.168. ...
随机推荐
- ML学习笔记之Anaconda中命令形式安装XGBoost(pip install)
0x00 概述 在没有安装XGBoost之前,import xgboot会出错,如下: # ModuleNotFoundError: No module named ‘xgboost’ 0x01 安装 ...
- LinkedList、ArrayList、Vector三者的关系与区别?
LinkedList.ArrayList.Vector三者的关系与区别? 区分ArrayList,Vector,LinkedList的区别 ArrayList,Vector的区别: 1.出现版本:Ar ...
- IIS 7.5绑定中文域名转码启动站点报“值不在预期的范围内”
问题现象 IIS 7.5在绑定中文域名转码后,启动站点会出现[值不在预期的范围内]: 解决方案 此问题是由于中文域名绑定错误导致的,IIS 7.5针对中文域名会自动转换为punycode码,所以不需要 ...
- 由一个空工程改为SpringBoot工程
1.先创建一个空的工程,创建springboot 工程 必须继承spring-boot-stater-parent 2.导入依赖 <parent> <groupId>org. ...
- 教你玩转Git-合并冲突
Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目.Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件.Git 与 ...
- HTML5深入学习之鼠标跟随,拖拽事件
知识点(鼠标跟随): mousedown: 当用户用鼠标点击在某一元素上就会触发该事件 mouseover: 当鼠标指针在某一元素上移动就会触发改事件 下面这个例子的效果就是鼠标点击元素后,元素跟着 ...
- 【总结】web工作代码分类整理(持续更新)
文件.blob 文件下载失败,将Blob对象转换为Json,处理异常错误? 使用FileReader,核心代码: var reader = new FileReader() reader.onload ...
- mongo数据库的一些命令(对于新同学,按照我的步骤连一遍即可)
进入mongo mongo 查看数据库 show dbs;/show databases(); 第一个命令简单(admin和local数据库是系统自带的) 进入/创建数据库 use 数据库名字(如果有 ...
- uni-app结合PHP实现单用户登陆
单用户登陆,即在一个应用中,同一个用户只能在线登陆一个,一个用户登陆,在其他设备上会被即时挤下线,确认后清空登陆该设备上的登陆装填并退回到登陆界面. uni-app是目前能通过使用vue.js框架只需 ...
- 【Python】列表推导式
1. 列表推导式 list1 = [1, 3, 5, 6, 8] list2 = [x * 2 for x in list1] print(list2) # [2, 6, 10, 12, 16]