CCF 201812-3 CIDR合并

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

 

#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<cmath>
using namespace std;
typedef struct IP {
	vector<int>bits;
	string s;
	int len, vis, real_len;
	IP(vector<int> a, string b, int c, int d) : bits(a), s(b), len(c), vis(d) {}
}ip;
vector<string>table;
vector<ip>file;
bool cmp(ip a, ip b) {
	for (int i = 0; i < 4; i++) 
		if (a.bits[i] != b.bits[i]) return a.bits[i] < b.bits[i];
	return a.len < b.len;
}
int int_change(string s) {
	int nums = 0;
	int len = s.size();
	for (int i = 0; i < len; i++) 
		nums += (s[i] - '0') * pow(10, len - i - 1);
	return nums;
}
string bits_change(int n) {
	vector<int>temp;
	string s;
	while (n >= 2) {
		temp.push_back(n % 2);
		n = n / 2;
	}
	temp.push_back(n);
	while (temp.size() != 8) temp.push_back(0);
	for (int i = temp.size() - 1; i >= 0; i--) s += (temp[i] + '0');
	return s;
}
void my_solve(string str) {
	vector<int>my_bits;
	string my_s;
	int my_len, cnt = 0, index = -1, l = 0, r = 0;
	for (int i = 0; i < str.size(); i++) {
		if (str[i] == '.' || str[i] == '/' || i == str.size() - 1) {
			int temp_len = (i == str.size() - 1) ? (i - l + 1) : (i - l);
			int t = int_change(str.substr(l, temp_len));
			my_bits.push_back(t);
			my_s += bits_change(t);
			l = i + 1, cnt++;
			if (str[i] == '/') break;
		}
	}
	my_len = (l < str.size()) ? int_change(str.substr(l, str.size() - l)) : cnt * 8;
	while (my_bits.size() < 4) my_bits.push_back(0);
	while (my_s.size() < 32) my_s += bits_change(0);
	file.push_back(IP(my_bits, my_s, my_len,1));
}
bool is_contain(ip a, ip b) {
	string s = a.s.substr(0, a.len);
	for (int i = 0; i < a.len; i++) {
		if (a.s[i] != b.s[i]) return false;
	}
	return true;
}
bool is_equal(int l, int r) {
	ip a = file[l], b = file[r];
	int flag = 0, index = -1;
	for (int i = 0; i < 32; i++) {
		if (a.s[i] != b.s[i]) {
			index = i;
			break;
		}
	}
	if (index == -1) {
		file[r].vis = 0;
		return true;
	}
	for (int i = index + 1; i < 32; i++) {
		if (a.s[i] != b.s[i]) {
			flag = 1;
			return false;
		}
	}
	string s = a.s.substr(0, index + 1);
	while (s.size() < 32) s += "0";
	if (flag == 0) {
		file[l].s = s;
		file[l].len -= 1;
		file[r].vis = 0;
	}
	return true;
}
void rechange_num(int index) {
	string s = file[index].s;
	int t = 0;
	while (t < 4) {
		int temp = 0;
		for (int i = t * 8; i < t * 8 + 8; i++) temp += (s[i] - '0') * pow(2, (8 - i - 1));
		file[index].bits[t] = temp;
		t++;
	}
}
int main() {
	int n;
	while (cin >> n) {
		file.clear(), table.clear();
		for (int i = 0; i < n; i++) {
			string str;
			cin >> str;
			table.push_back(str);
		}
		for (int i = 0; i < table.size(); i++) my_solve(table[i]);
		sort(file.begin(), file.end(), cmp);
		int l = 0, r = 1;
		while (l < file.size()) {
			while (l < file.size() && file[l].vis == 0) l++;
			r = l + 1;
			while (r < file.size() && file[r].vis == 0) r++;
			if (l >= file.size()) break;
			if (r >= file.size()) {
				l++, r = l + 1;
				continue;
			}
			if (is_contain(file[l], file[r])) {
				file[r].vis = 0;
				r++;
			}
			else if (file[l].len == file[r].len && is_equal(l, r)) r++;
			else {
				l++, r = l + 1;
			}
		}

		for (int i = 0; i < file.size(); i++) {
			if (file[i].vis == 1) {
				for (int j = 0; j < 4; j++) {
					cout << file[i].bits[j];
					if (j == 3) cout << '/';
					else cout << '.';
				}
				cout << file[i].len << endl;
			}
		}
	}
	return 0;
}

90分的代码。。实力有限,不知道为什么超时,希望大佬知道的指点一下。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值