201812 CSP认证 | CIDR合并

news2025/1/9 1:16:22

CIDR合并
难是真的不难但是也写了我几个小时服了
这道题在有计网的基础上就很好理解了,没有在格式上有任何刁难你的。这里不讲背景了
官网提交结果以及满分代码如下:
在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<string, int> PSI;
const int N = 1e5 + 10;
int n;
struct node{
    string ip;
    int len;
    ll ten;  //ip前缀的十进制表示:为了方便排序
};
vector<node> ipPool;
vector<node> merge1; //第一轮合并的结果
vector<node> res;   //同级合并的最终结果
int to_int(string str)
{
    stringstream ssin(str);
    int x;
    ssin >> x;
    return x;
}
string to_str(int m)
{
    stringstream ssin;
    ssin << m;
    string str;
    ssin >> str;
    return str;
}
//用于第一步排序
bool cmp(node x, node y)
{
    if(x.ten == y.ten) return x.len < y.len;
    else return x.ten < y.ten;
}
//处理一个输入的ip,将其处理后存储到ipPool中
void handle(string str)
{
    int k = str.find('/');
    int len = 0; node temp;
    if(k != -1)  { len = to_int(str.substr(k + 1)); str = str.substr(0, k); }

    //开始解析ip, 将字符串按照'.'分割开来
    vector<string> vec;
    for(int i = 0, j = 0; i < str.size(); i = j + 1){  //将str用'+'分割开来
        j = str.find('.', i);  //从下标i开始找+号
        if(j == -1) j = str.size();
        vec.push_back(str.substr(i, j - i));
    }
    if(!len) len = vec.size() * 8;  //省略了长度型的ip书写方式

    if(vec.size() != 4){
        int sz = vec.size();
        for(int i = 1;i <= 4 - sz;i ++){
            vec.push_back("0");  //补0
        }
    }
    string ip = ""; ll ten = 0;  //将ip转化为十进制的数字
    for(int i = 0;i < vec.size();i ++) {
        ip = ip + vec[i] + '.';
        ll x = to_int(vec[i]);
        x <<= ((3 - i) * 8);
        ten += x;
    }

    ip = ip.substr(0, ip.size() - 1); //删去最后一个点
    ip += "/" + to_str(len);

    temp.ip = ip; temp.len = len; temp.ten = ten;
    ipPool.push_back(temp);
}

//判断ipPool中b位置ip的匹配集是否是a位置ip匹配集的子集
bool subset(int a, int b)
{
    int lena = ipPool[a].len, lenb = ipPool[b].len;
    if(lena > lenb) return false;

    //接下来是lena <= lenb的情况,也就是二者的前lena个bit位置必须相同
    int delta = 32 - lena;
    int tena = ipPool[a].ten >> delta, tenb = ipPool[b].ten >> delta;  //只保留前lena位

    int temp = tena ^ tenb;
    if(temp) return false;  //前lena个bit位不相同
    return true;
}
//将ipPool中的元素从小到大进行合并
void small_Large_Merge()
{
    int a = 0, b = 1;
    bool st[N]; //考虑某个位置的元素是否存在
    memset(st, true, sizeof st);
    while(b < n){    //n也是ipPool的大小
        if(subset(a, b)){ st[b] = false; b ++; }
        else{ a = b; b ++; }
    }

    for(int i = 0;i < n;i ++){
        if(st[i]) merge1.push_back(ipPool[i]);
    }
}
//对merge1进行同级合并
void final_Merge()
{
    int a = 0, b = 1, sz = merge1.size();
    bool st[N];
    memset(st, true, sizeof st);  //功能同前面相同
    while(b < sz){
        node t;  //存储中间结果
        int lena = merge1[a].len, lenb = merge1[b].len;
        bool flag = false;  //是否能合并
        if(lena == lenb){
            //看二者是否能合并, 也就是看前len - 1位置是否完全相同,且最后一位不同
            int delta = 32 - lena;
            int tena = merge1[a].ten >> delta, tenb = merge1[b].ten >> delta;
            int tena2 = merge1[a].ten >> (delta + 1), tenb2 = merge1[b].ten >> (delta + 1);
            int cnt = 0;   //用来记录前len位有几位不相同
            int temp = tena ^ tenb;
            while(temp){
                cnt ++;
                temp &= (temp - 1);
            }

            temp = tena2 ^ tenb2;
            if(!temp && cnt == 1){  //前len - 1相同,第len不同,可以合并
                flag = true;
                t.ten = merge1[a].ten;
                t.len = merge1[a].len - 1; //长度不同
                string ip = merge1[a].ip;
                int k = ip.find('/');
                ip = ip.substr(0, k + 1);
                ip += to_str(t.len);
                t.ip = ip;
            }
        }
        if(flag){
            merge1[a] = t; st[b] = false;  //更新; a向前回溯
            if(a > 0){   //a > 0才有回溯的必要,注意这里st[0]是不可能为false的
                b = a; a --;
                while(!st[a]) a --;
            }
            else { //无需向前找了
                while(b < sz && !st[b]) b ++;
            };
        }
        else {
            a = b;
            b ++;
            while(b < sz && !st[b]) b ++;
        }
    }
    for(int i = 0;i < sz;i ++){
        if(st[i]) res.push_back(merge1[i]);
    }
}

int main()
{
    ios::sync_with_stdio(false); cin.tie(0);cout.tie(0);

    cin >> n;
    for(int i = 0;i < n;i ++){
        string ip; cin >> ip;
        handle(ip);
    }
    sort(ipPool.begin(),ipPool.end(), cmp);

    //现在开始从小到大合并
    small_Large_Merge();
    //同级合并
    final_Merge();
    for(auto x : res){
        cout << x.ip << endl;
    }

    return 0;
}

本题我用了位运算来实现。能否合并的关键就是看前几位是否是相同的,如果前x位相同,第x + 1的异或结果为1的话,此时两个就可以合并成一个。因此我设置了一个len来保存ip地址的十进制数。
但就是这个我改了很久的错误
第62行我的初始代码是:ten += ( x << ((3 - i) * 8) ),结果总是负数
后来又测试了几个如下:
在这里插入图片描述
其实就是符号的问题。
如果我直接对128移位置,只在低位补零;此时的x的表示形式就是10000000 0000000 0000000 0000000。从补码的角度来说,因为最高位为1,此时就是负数!!!
而我若先赋值为128,此时这个数据只是存在与x空间的存储形式为00000000 00000000 00000000 10000000,再移位;此时变为00000000 10000000 0000000 0000000 0000000最高位仍然为0

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1546968.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Qt Design Studio 软件怎么用(详细+通俗+有趣)

建议&#xff1a;本文长期更新&#xff0c;建议点赞/收藏&#xff01; 1. 啥是Qt Design Studio&#xff1f; Qt Design Studio 是一个用于设计和开发用户界面的工具&#xff0c;特别适合开发跨平台应用程序。它结合了UI设计和开发的工作流程&#xff0c;使得设计师和开发者可…

​奶茶店小程序有哪些功能

​奶茶店作为饮品行业的一种热门经营模式&#xff0c;拥有自己的小程序可以带来诸多便利和增长机会。在这篇文章中&#xff0c;我们将探讨奶茶店小程序应该具备的功能&#xff0c;以满足消费者的需求&#xff0c;提升店铺的运营效率和用户体验。 1. **在线订购功能**&#xff…

linux文本三剑客 --- grep、sed、awk

1、grep grep&#xff1a;使用正则表达式搜索文本&#xff0c;将匹配的行打印出来&#xff08;匹配到的标红&#xff09; 命令格式&#xff1a;grep [option] pattern file <1> 命令参数 -A<显示行数>&#xff1a;除了显示符合范本样式的那一列之外&#xff0c;并…

Windows/Mac 上的 7 个顶级数据恢复软件榜单

数据恢复软件可帮助您从众多存储设备中恢复损坏或删除的数据。该文件恢复软件可以恢复文件、文档、视频、照片等。这些应用程序支持许多标准文件格式&#xff0c;如 PNG、RTF、PDF、HTML、JPG、MP3 等。以下是具有流行功能的顶级数据恢复软件列表和网站链接。磁盘恢复软件列表包…

【Python系列】Python 中 YAML 文件与字典合并的实用技巧

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

真假难辨:凯特王妃最新视频疑似AI合成,公众哗然!

会议之眼 快讯 北京时间3月23日凌晨&#xff0c;英国的凯特王妃发布了一段震撼人心的视频声明&#xff0c;坦诚自己正在面临一场艰难的挑战——患上了癌症。她坦言目前正在接受预防性化疗&#xff0c;并处于治疗的“早期阶段”&#xff0c;这一消息是在她暂时退出公众生活两个多…

智慧城市一屏统览,数字孪生综合治理

现代城市作为一个复杂系统&#xff0c;牵一发而动全身&#xff0c;城市化进程中产生新的矛盾和社会问题都会影响整个城市系统的正常运转。智慧城市是应对这些问题的策略之一。城市工作要树立系统思维&#xff0c;从构成城市诸多要素、结构、功能等方面入手&#xff0c;系统推进…

力扣Lc21--- 389. 找不同(java版)-2024年3月26日

1.题目描述 2.知识点 &#xff08;1&#xff09;在这段代码中&#xff1a; // 统计字符串s中每个字符的出现次数for (int i 0; i < s.length(); i) {count[s.charAt(i) - a];}对于字符串s “abcd”&#xff1a; 当 i 0&#xff0c;s.charAt(i) ‘a’&#xff0c;ASCII…

Kali开启远程服务

一&#xff0c;先切换root账户 二、kali开启远程服务 1&#xff0c;修改远程登录的配置文件 vim /etc/ssh/sshd_config &#xff08;用文本编辑器打开此文件) 在文件的普通模式下&#xff0c;使用/PermitRootLogin&#xff0c;回车&#xff0c;查找到该行&#xff0c;i&#…

鸿蒙OS开发实例:【demo选择列表限定数量】

效果图&#xff1a; 示例代码 // 使用 DevEco Studio 3.1.1 Release 及以上版本&#xff0c;API 版本为 api 9 及以上。 // 主要功能及注意事项&#xff1a; // 该组件展示了一个乘客选择列表。列表中的每个项目包含一个复选框和对应的乘客姓名&#xff0c; // 用户点击任意一…

Redis如何应对缓存穿透问题——Java全栈知识(9)

我们在正常使用缓存的时候的流程大概就是这样的&#xff1a; 请求访问缓存&#xff0c;缓存有数据就返回&#xff0c;缓存无数据就去数据库里面查数据写入到缓存中。 1、缓存穿透问题 但是如果由恶意请求&#xff0c;短时间内大量的访问不存在的数据&#xff0c;这时每个请求…

工作中遇到的疑难杂症,以及解决办法

一 pagehelper和自定义mybatis拦截器冲突bug 1.1 问题描述 当在springboot工程&#xff0c;持久层使用mybatis&#xff0c;且使用pagehelper实现分页功能&#xff0c;当随着业务发展&#xff0c;需要自定义一个mybatis的拦截器实现sql的打印&#xff0c;但是出现拦截器失效&…

flac和mp3可以互相转换吗?flac和mp3互相转换的方法

一&#xff0c;什么是FLAC格式 FLAC即是Free Lossless Audio Codec的缩写&#xff0c;中文可解为无损音频压缩编码。FLAC是一套著名的自由音频压缩编码&#xff0c;其特点是无损压缩。不同于其他有损压缩编码如MP3 及 AAC&#xff0c;它不会破坏任何原有的音频资讯&#xff0c…

【保姆级教程】YOLOv8自动数据标注

一、YOLOV8环境准备 1.1 下载安装最新的YOLOv8代码 仓库地址&#xff1a; https://github.com/ultralytics/ultralytics1.2 配置环境 pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple1.3 安装labelme标注工具 pip install labelme二、半自动标注…

MATLAB 自定义生成直线点云(详细介绍) (47)

MATLAB 自定义生成直线点云 (详细介绍)(47) 一、算法介绍二、具体步骤二、算法实现1.代码2.效果一、算法介绍 通过这里的直线生成方法,可以生成模拟直线的点云数据,并通过调整起点、终点、数量和噪声水平等参数来探索不同类型的直线数据。这种方法可以用于测试、验证和开…

【考研数学】跟武忠祥,如何使用好《复习全书》和《高数辅导讲义》?

本人就是全程跟武忠祥老师高分上岸的&#xff01; 高数辅导讲义建议在强化阶段再买就行 在基础阶段把基础篇吃透就ok 本人属于基础很差相当于是零基础的考研党&#xff0c;经过一年备考成功上岸 中间花费了很多时间在考研数学备考信息检索上&#xff0c;写下这篇希望能帮助…

H264码流结构介绍

H264的码流格式 一般有两种格式&#xff1a; 1、Annex B&#xff08;字节流格式&#xff09;&#xff1a;由Network Abstraction Layer Units (NALU)组成&#xff0c;也被称为NAL。每个NALU包都可以被单独解析和处理。 2、MP4格式&#xff0c;也叫RTP包格式。MP4 格式没有起始…

Java Web-Maven

Maven是apache旗下的一个开源项目&#xff0c;是一款用于管理和构建java项目的工具 Maven的作用 1.依赖管理:方便快捷的管理项目依赖资源(jar包)&#xff0c;避免版本冲突问题 我们有的项目需要大量的jar包&#xff0c;采用手动导包的方式非常繁琐&#xff0c;并且版本升级也…

睿眼(Realeye)视觉识别模型训练全流程心得分享

睿眼&#xff08;Realeye&#xff09;是一款集智能采集、识别、定位、抓取、视控全流程为一体的 AI 产品&#xff0c; 以其 AI 算法结合机械臂硬件实现对万事万物的定位抓取功能&#xff0c;能够实现对任意目标物从图 片采集、标注到模型训练和抓取。通过人性化的交互方式、易操…

深度剖析python的就业面

技术行业&#xff0c;一定要提升技术功底&#xff0c;丰富项目实战经验&#xff1b; 这对于你未来几年职业规划&#xff0c;以及测试技术掌握的深度非常有帮助。 WEB开发 尽管目前Python并不是做Web开发的首选&#xff0c;但这仍是一个比较热门的方向。 现如今有不少知名网…