CCF CSP认证 201812-3 CIDR合并 (01Trie) (100分)

所有的ip前缀可以构成一棵01Trie,每个ip地址对应Trie上的一棵叶子结点,那么题意就是选出尽可能少的结点,使其子树中包含所有给出前缀的叶子结点,dp即可

非标准解法,没看提示,被卡内存了很难受~~

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int N=4e7+10,inf=0x3f3f3f3f;
 5 int n,ch[N][2],ed[N],tot;
 6 int newnode() {int u=++tot; ch[u][0]=ch[u][1]=ed[u]=0; return u;}
 7 typedef vector<string> Vec;
 8 Vec split(string S,char C) {
 9     Vec vec;
10     string s;
11     for(char c:S) {
12         if(c!=C)s.push_back(c);
13         else vec.push_back(s),s.clear();
14     }
15     vec.push_back(s),s.clear();
16     return vec;
17 }
18 int rev(int x,int n) {int ret=0; for(int i=0; i<n; ++i)ret=ret<<1|(x>>i&1); return ret;}
19 int keep(int x,int d) {return x&((1<<d)-1);}
20 struct IP {int x,l;};
21 IP strtoIP(string s) {
22     Vec vec=split(s,'/');
23     int l=-1;
24     if(vec.size()==2)sscanf(vec[1].c_str(),"%d",&l);
25     vec=split(vec[0],'.');
26     if(l==-1)l=8*vec.size();
27     int x=0;
28     for(int i=0; i<vec.size(); ++i) {
29         int y;
30         sscanf(vec[i].c_str(),"%d",&y);
31         x|=rev(y,8)<<(8*i);
32     }
33     return {x,l};
34 }
35 string IPtostr(IP ip) {
36     int a[4];
37     char buf[25];
38     for(int i=0; i<4; ++i)a[i]=rev(keep(ip.x>>(8*i),8),8);
39     sprintf(buf,"%d.%d.%d.%d/%d",a[0],a[1],a[2],a[3],ip.l);
40     return string(buf);
41 }
42 void ins(IP ip) {
43     int u=1;
44     for(int i=0; i<ip.l; ++i) {
45         int f=ip.x>>i&1;
46         if(!ch[u][f])ch[u][f]=newnode();
47         u=ch[u][f];
48     }
49     ed[u]=1;
50 }
51 void dfs1(int u) {
52     if(!u)return;
53     dfs1(ch[u][0]),dfs1(ch[u][1]);
54     ed[u]=ed[u]||(ed[ch[u][0]]&&ed[ch[u][1]]);
55 }
56 void dfs2(int u,IP ip) {
57     if(!u)return;
58     if(ed[u]) {cout<<IPtostr(ip)<<endl; return;}
59     dfs2(ch[u][0], {ip.x,ip.l+1}),dfs2(ch[u][1], {ip.x|(1<<ip.l),ip.l+1});
60 }
61 
62 int main() {
63     scanf("%d",&n);
64     char buf[100];
65     tot=0,newnode();
66     while(n--) {
67         scanf("%s",buf);
68         string s=buf;
69         IP ip=strtoIP(s);
70         ins(ip);
71     }
72     dfs1(1);
73     dfs2(1, {0,0});
74     return 0;
75 }

 

posted @ 2020-09-03 19:48  jrltx  阅读(213)  评论(0编辑  收藏  举报