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\n",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<< "\n"; 
113     }
114     return 0;
115 }
网上list版代码

 

posted @ 2019-11-05 17:42  神犇(shenben)  阅读(526)  评论(0编辑  收藏  举报