• 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+5;
    struct IP{UI val,a[5];}ip[N];//a[0]~a[3]表示IP地址,a[4]表示题目中的len 
    //val表示IP地址的十进制形式(主要作用:IP前缀能表示的数值范围)
    char str[33];int n;
    void dealStr(int id){//字符串点分数字,转换成标准型
        scanf("%s",str);
        int cnt(0),pn(0),xn(0),len=strlen(str);//pn点的数量,sn斜杠的数量 
        for(int i=0;i<len;i++){
            if(str[i]=='.') pn++;else 
            if(str[i]=='/') xn++;
        }
        for(int i=0;i<5;i++) ip[id].a[i]=0;
        char *p1=str,*p2,tmp[6];
        for(int i=0;i<pn;i++){
            p2=strchr(p1,'.');
            strncpy(tmp,p1,p2-p1);//strncpy复制从p1中p2-p1长度的字符串到tmp中 
            tmp[p2-p1]=0;
            ip[id].a[cnt++]=atoi(tmp);
            p1=p2+1;
        }
        if(xn){
            p2=strchr(p1,'/');//strchr从p1中查找‘/’第一次出现的位置 
            strncpy(tmp,p1,p2-p1);
            tmp[p2-p1]=0;
            ip[id].a[cnt++]=atoi(tmp);//atoi 字符串转数字 
            p1=p2+1;
            strcpy(tmp,p1);
            ip[id].a[4]=atoi(tmp);
        }
        else{
            strcpy(tmp,p1);
            ip[id].a[cnt++]=atoi(tmp);
            ip[id].a[4]=cnt*8;
        }
        ip[id].val=0;//计算ip十进制值 
        for(int i=0;i<4;i++) ip[id].val+=ip[id].a[i]<<8*(3-i);
    }
    inline bool cmp(const IP &ip1, const IP &ip2){
        for(int i=0;i<5;i++) if(ip1.a[i]!=ip2.a[i]) return ip1.a[i]<ip2.a[i];
        return 0;
    }
    inline void range(IP &ip0,UI &l,UI &r){//计算IP前缀能表示的数值范围
        UI len=32-ip0.a[4];
        l=ip0.val>>len<<len;
        r=ip0.val|((1<<len)-1);
    }
    void union1(){//从小到大合并 
        int p=0;
        UI la,lb,ra,rb;
        for(int i=1;i<n;i++){
            range(ip[p],la,ra);
            range(ip[i],lb,rb);
            if(la>lb||rb>ra) ip[++p]=ip[i];
        }
        n=p+1;
    }
    inline bool judgeUnion(IP &ip1,IP &ip2,IP &res){//判断同级能否合并 
        if(ip1.a[4]!=ip2.a[4]||ip1.a[4]<1) return 0;
        res=ip1;res.a[4]--;
        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+1) return 1;
        return 0;
    }
    void union2(){
        int p=0;IP res;
        for(int i=1;i<n;i++){
            if(judgeUnion(ip[p],ip[i],res)){
                ip[p]=res;
                while(p>0&&judgeUnion(ip[p-1],ip[p],res)) ip[--p]=res;
            } 
            else{
                ip[++p]=ip[i];
            }
        }
        n=p+1;
    }
    int main(){
        scanf("%d",&n);
        for(int i=0;i<n;i++) dealStr(i);
        std::sort(ip,ip+n,cmp);
        union1();
        union2();
        for(int i=0;i<n;i++) printf("%u.%u.%u.%u/%u
    ",ip[i].a[0],ip[i].a[1],ip[i].a[2],ip[i].a[3],ip[i].a[4]);
        return 0;
    }
      1 #include <bits/stdc++.h>
      2 
      3 using namespace std;
      4 
      5 const int maxn = 1e5 + 5;
      6 
      7 struct node {
      8     int ip[4] , len , ip4[33];
      9     unsigned int d;
     10     node(string s) {
     11         bool flag = 0;
     12         int cnt = 0;
     13         d = len = 0; 
     14         memset(ip,0,sizeof(ip));
     15         for(int i = 0 ; i < s.length() ; i++) {
     16             if(s[i] == '.')continue;
     17             else if(s[i] == '/')  {
     18                 flag = 1;continue;
     19             }
     20             else {
     21                 int t = 0;
     22                 while(isdigit(s[i])) {
     23                     t = t * 10 + s[i] - '0';
     24                     i++;                        
     25                 }
     26                 i--;
     27                 if(!flag)ip[cnt++] = t;
     28                 else len = t;
     29             }
     30         }
     31         if(!len)len = cnt * 8;
     32         cnt = 7;
     33         for(int i = 0 ; i < 4 ; i++) {
     34             d = d * 256 + ip[i];
     35             int t = ip[i];
     36             for(int j = cnt ; j >= cnt - 7 ; j--) {
     37                 ip4[j] = t % 2;
     38                 t /= 2;
     39             }
     40             cnt += 8;
     41         }
     42     } 
     43     node(){}
     44     bool operator < (const node b) const {
     45         return d < b.d || (d == b.d && len < b.len);
     46     }
     47 }; 
     48 
     49 node a[maxn];
     50 list<node> ans;
     51 bool vis[maxn];
     52 
     53 bool judge(node b , node c) {
     54     if(c.len < b.len)return false;
     55     for(int i = 0 ; i < b.len ; i++) {
     56         if(b.ip4[i] != c.ip4[i]) {
     57             return false;    
     58         }
     59     }
     60     return true;
     61 }
     62 
     63 bool judge1(node b , node c) {
     64     if(c.len != b.len || c.len == 0)return false;
     65     for(int i = 0 ; i < b.len - 1 ; i++) {
     66         if(b.ip4[i] != c.ip4[i])return false;
     67     }
     68     int len = b.len - 1;
     69     if(b.ip4[len] != c.ip4[len]) return true;
     70     else return false;
     71 }    
     72 
     73 int main() {
     74     int n;
     75     ios::sync_with_stdio(0);
     76     cin.tie(0);cout.tie(0);
     77     cin >> n;
     78     for(int i = 0 ; i < n ; i++) {
     79         string s;
     80         cin >> s;
     81         a[i] = node(s);
     82     } 
     83     sort(a , a + n);
     84     for(int i = 0 ; i < n ; ) {
     85         int p = i;
     86         i++;
     87         while(i < n && !vis[i]) {
     88             if(judge(a[p] , a[i])) {
     89                 vis[i] = 1;
     90                 i++;
     91             }
     92             else break;
     93         }
     94     }
     95     for(int i = 0 ; i < n ; i++) {
     96         if(!vis[i])ans.push_back(a[i]);
     97     }
     98     for(auto t = ans.begin() ; t != ans.end() ; t++) {
     99         auto t1 = t;
    100         t1++;
    101         while(t1 != ans.end() ) {    
    102             if(judge1(*t , *t1)) {
    103                 t -> len = t -> len - 1;
    104                 ans.erase(t1);
    105                 if(t != ans.begin())t--;
    106                 t1 = t; t1++;
    107             }
    108             else break;
    109         }
    110     }
    111     for(auto t = ans.begin() ; t != ans.end() ; t++) {
    112         cout << t -> ip[0] << "."<< t -> ip[1] << "." << t -> ip[2] << "." << t -> ip[3] << "/" << t -> len<< "
    "; 
    113     }
    114     return 0;
    115 }
    网上list版代码
  • 相关阅读:
    python 序列排序 排序后返回相应的索引
    海明距离
    hive学习01词频统计
    自然语言处理之LCS最长公共子子序列
    自然语言处理之关键词提取TF-IDF
    自然语言处理之比较两个句子的相似度 余弦相似度
    linux命令tar压缩解压
    linux学习之软件包安装
    集群间数据迁移报错
    hive学习04-员工部门表综合案例
  • 原文地址:https://www.cnblogs.com/shenben/p/11800059.html
Copyright © 2020-2023  润新知