题目大意:
给你一些ip地址,ip地址的表示方式点分十进制加子网掩码,让你求出与给出的网络号没有重复网段并且所有网络号合并可以组成整个网络同时保证你列举 出来的网络数量最少,将网络地址输出。
这道题目模型是一棵树,问题可以抽象成询问需要加多少个节点使得树的每一个父亲都有两个儿子。
树的表示方法深度表示的ip中的第几位,一个节点遇到0到左儿子遇到1到右儿子,这样每个ip地址都可以用树上的一条路径表示出来,深蓝色的点表示根,黄色点表示遍历过的点,深蓝色表示的终止节点,红色表示是要添加的点对应的路径转化后就是最后要输出的答案。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<map>
#include<stdlib.h>
using namespace std;
#define INF 0x80000000
#define Nim 0xff
int T;
int tt = 1;
bool ok;
struct node{
unsigned int ip;
int net;
node(unsigned int t = 0,int s = 0){
ip = t;net = s;
}
};
map<long long int,bool>b;
map<long long int,bool>fk;
node t;
vector<node> v;
void insert(long long int rt,int k){
b[rt] = 1;
if(k>=t.net){fk[rt]=1;return;}
int now = (t.ip&(INF>>k))>>(31-k);
if(now==0)insert(rt<<1,k+1);
if(now==1)insert(rt<<1|1,k+1);
}
unsigned int st;
void print(node now){
int l[4];unsigned int tem = now.ip;
for(int i=0;i<4;i++){
l[i] = tem&Nim;
tem>>=8;
}
printf("%d",l[3]);
for(int i=2;i>=0;i--){
printf(".%d",l[i]);
}
printf("/%d\n",now.net);
}
void output(){
printf("Case #%d:\n",tt++);
if(v.size()==0){printf("0\n");return;}
else{
printf("%d\n",v.size());
for(int i=0;i<v.size();i++){
print(v[i]);
}
}
}
void dfs(long long int rt,int k){
//cout<<rt<<" "<<v.size()<<endl;system("PAUSE");
if(fk[rt])return;
if(b[rt]==0){
if(rt%2==0){
if(b[rt|1]){
v.push_back(node(st,k));
}
}else{
if(b[rt-1]){
v.push_back(node(st,k));
}
}
return;
}
unsigned int tem = st;
dfs(rt<<1,k+1);
st = tem|(INF>>k);
dfs(rt<<1|1,k+1);
st = tem;
}
void test(){
for(int i=0;i<10;i++){
cout<<fk[i]<<" ";
}cout<<endl;
for(int i=0;i<10;i++){
cout<<b[i]<<" ";
}cout<<endl;
}
int main(){
scanf("%d",&T);
while(T--){
ok = 0;
v.clear();
int num;b.clear();fk.clear();
scanf("%d",&num);if(num==0){printf("Case #%d:\n",tt++);printf("1\n");printf("0.0.0.0/0\n");continue;}
for(int i=0;i<num;i++){
int a;char b;
unsigned tem =0;
for(int j=0;j<4;j++){
scanf("%d%c",&a,&b);
tem<<=8;
tem+=a;
}
//cout<<tem<<endl;
t.ip = tem;scanf("%d",&t.net);
if(t.net==0)ok = 1;
insert(1,0);
}
st = 0;
dfs(1,0);// test();
output();
}
}