UVALive 7043 International Collegiate Routing Contest(字典

题意:

输入IPv4地址空间中的一些子网号,构成一个网络集合。 输出个数最小的一个网络集合,要求其与输入集合没有交集,且相对与IPv4地址空间全集,与输入集合互为补集。 输出集合包含的子网号,格式遵循网络规范。

解析:

这题可以用Trie树来搞。 每个IP地址由32位二进制组成。整个地址空间可以表现为一棵二叉树。 用Trie的节点标记每个二进制串所能抵达的终点,即子网覆盖的终点位置。 建立Trie树后,DFS遍历树上的分支,输出没有被覆盖的分支即可。

;ll;const int maxnode = (int)5e5 + 10;const int sigma_size = 2;vector<string> ans;struct Trie {int ch[maxnode][2];bool val[maxnode];int sz;void clear() { sz = 1; memset(ch[0], 0, sizeof(ch[0])); }Trie() { clear(); }int idx(char c) { return c – ‘0’; }void insert(char* s, int len) {int u = 0;for(int i = 0; i < len; i++) {int c = idx(s[i]);if(!ch[u][c]) {memset(ch[sz], 0, sizeof(ch[sz]));val[sz] = false;ch[u][c] = sz++;}u = ch[u][c];}val[u] = true;}void setIp(ll ip, int len) {int a[4];char buf[30];for(int i = 3; i >= 0; i–) {a[i] = ip % 256;ip >>= 8;}sprintf(buf, “%d.%d.%d.%d/%d”, a[0], a[1], a[2], a[3], len+1);ans.pb(buf);}void dfs(int u, int dep, ll cur) {if(val[u]) return;for(int i = 1; i >= 0; i–) {ll ip = cur | ((ll)i << (31-dep));if(!ch[u][i])setIp(ip, dep);elsedfs(ch[u][i], dep+1, ip);}}} trie;int n;char bit[33];void trans(char* s, ll ip) {for(int i = 31; i >= 0; i–)s[31-i] = ((ip >> i) & 1) + ‘0’;s[32] = ‘\0’;}ll getIp(ll a, ll b, ll c, ll d) {return (1LL << 24) * a + (1LL<<16) * b + (1LL<<8) * c + d;} int main() {int T, cas = 1;scanf(“%d”, &T);while(T–) {trie.clear();ans.clear();scanf(“%d”, &n);printf(“Case #%d:\n”, cas++);if(n == 0) {puts(“1\n0.0.0.0/0”);continue;}ll a, b, c, d, len, ip;for(int i = 0; i < n; i++) {scanf(“%lld.%lld.%lld.%lld/%lld”, &a, &b, &c, &d, &len);ip = getIp(a, b, c, d);trans(bit, ip);trie.insert(bit, len);}trie.dfs(0, 0, 0);int size = ans.size();printf(“%d\n”, size);for(int i = 0; i < size; i++) {printf(“%s\n”, ans[i].c_str());}}return 0;}

,怪天怪地,我都不会怪你,你有选择幸福的权利…

UVALive 7043 International Collegiate Routing Contest(字典

相关文章:

你感兴趣的文章:

标签云: