CCF201812-3 CIDR合并(100分)位运算+文本
Posted 海岛Blog
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CCF201812-3 CIDR合并(100分)位运算+文本相关的知识,希望对你有一定的参考价值。
试题编号: 201812-3
试题名称: CIDR合并
时间限制: 1.0s
内存限制: 512.0MB
样例输入
2
1
2
样例输出
1.0.0.0/8
2.0.0.0/8
样例输入
2
10/9
10.128/9
样例输出
10.0.0.0/8
样例输入
2
0/1
128/1
样例输出
0.0.0.0/0
问题链接:CCF202104-1 灰度直方图
问题简述:(略)
问题分析:按题意进行处理即可,有2次合并处理。
程序说明:(略)
参考链接:(略)
题记:位运算巧妙,输入文本处理简洁。
AC的C++语言程序如下:
/* CCF201812-3 CIDR合并 */
#include <bits/stdc++.h>
using namespace std;
const int N = 100000 + 1;
struct Node {
unsigned int num;
int len;
bool flag;
} ip[N], ip2[N];
int ipcnt = 0;
bool cmp(Node a, Node b)
{
return a.num == b.num ? a.len < b.len : a.num < b.num;
}
void iptok(char s[])
{
unsigned int num[4] = {0, 0, 0, 0};
int cnt = 0, len = 0, flag = 0;
for (int i = 0; s[i]; i++)
if (s[i] == '.') cnt++;
else if (s[i] == '/') flag = 1;
else {
if (flag) len = len * 10 + s[i] - '0';
else num[cnt] = num[cnt] * 10 + s[i] - '0';
}
if (flag == 0) {
int pcnt = 0;
for (int i = 0; s[i]; i++)
if (s[i] == '.') pcnt++;
len = pcnt * 8 + 8;
}
ip[++ipcnt].len = len;
ip[ipcnt].flag = true;
ip[ipcnt].num = (((num[0] * 256) + num[1]) * 256 + num[2]) * 256 + num[3];
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(NULL);
cout.tie(NULL);
int n;
char s[20];
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> s;
iptok(s);
}
sort(ip + 1, ip + 1 + n, cmp);
int cnt = 1;
ip2[cnt] = ip[cnt];
for (int i = 2; i <= n; i++)
for (int j = 0; j < ip2[cnt].len; j++)
if (((ip[i].num >> (31 - j)) & 1) != ((ip2[cnt].num >> (31 - j)) & 1)) {
ip2[++cnt] = ip[i];
break;
}
for (; ;) {
bool flag = false;
int k;
for (int i = 1; i <= cnt; i++)
if (ip2[i].flag) {
k = i;
break;
}
for (int i = k + 1; i <= cnt; i++)
if (ip2[i].flag) {
if (ip2[i].len == ip2[k].len) {
for (int j = 0; j < ip2[i].len - 1; j++)
if (((ip2[i].num >> (31 - j)) & 1) != ((ip2[k].num >> (31 - j)) & 1)) {
k = i;
break;
}
if (k != i) {
ip2[k].len -= 1;
ip2[i].flag = false;
flag = true;
}
} else
k = i;
}
if (!flag) break;
}
for (int i = 1; i <= cnt; i++)
if (ip2[i].flag) {
unsigned int a = ip2[i].num >> 24;
unsigned int b = (ip2[i].num % (256 * 256 * 256)) >> 16;
unsigned int c = (ip2[i].num % (256 * 256)) >> 8;
unsigned int d = ip2[i].num % 256;
cout << a << "." << b << "." << c << "." << d << "/" << ip2[i].len << endl;
}
return 0;
}
以上是关于CCF201812-3 CIDR合并(100分)位运算+文本的主要内容,如果未能解决你的问题,请参考以下文章