LuoguP7911 [CSP-J 2021] 网络连接 题解

Content

题目过于难解释,请前往题面查看。以下直接给出本题做法。

Solution

入门组 T3 在我印象中向来都不是很容易能做出来的题目,但是今年这个 T3 不得不说还是挺好做的。

我们先不妨令它给出的地址串是合法的,也就是测试点 \(1\sim 11\) 的特殊性质,我们直接用个 map 来存储每个地址串是否已有服务器建立连接,即可解决判断地址串是否已经在前面有服务机建立连接的这个问题,同时对于客户机,这也同样可以判断是否有建立连接的服务机供其连接。

这样,判断给出的地址串是否合法就变成了我们接下来要重点解决的问题。

我们回到题面看看不合法的字符串可能是什么样的:

不是形如 a.b.c.d:e 格式的字符串,例如含有多于 \(3\) 个字符 . 或多于 \(1\) 个字符 : 等情况。

整数 \(a,b,c,d,e\) 中某一个或多个超出上述范围(即 \(0\leqslant a,b,c,d\leqslant 255\)\(0\leqslant e\leqslant 65535\));

整数 \(a,b,c,d,e\) 中某一个或多个含有多余的前导 \(0\)

我们根据每个特点将其转化成代码语言。

首先对于不是形如 a.b.c.d;e 格式的地址串,我们直接扫一遍判断其是否恰好有 \(3\).\(1\). 即可。同时,我们将第一个 . 前面的部分、第一个 . 和第二个 . 之间的部分、第二个 . 和第三个 . 之间的部分、第三个 .: 之间的部分、: 后面的部分分别提取出来,将字符串的这五个部分分别记作 \(s_1,s_2,s_3,s_4,s_5\)

之后,对于每个 \(s_i\),我们首先看 \(s_i\) 的首字符是否是 0,然后再去将其转化成数字。在转换的过程中我们需要判断数字是否超出了范围,一旦超出了范围就直接判定其不合法即可。注意,这里之所以在转换的过程中就判断其是否超出范围是因为,如果直接全部转换完再判断,容易超出数据类型范围从而使最终的转换结果不准确。当然地址串的长度不超过 \(\sout{25}\),所以直接用 __int128 是可以保证不爆炸的,但是这里显然不必要用这么大的数据类型去判断一个很小的数字,用上述方法即可仅使用普通的 int 解决是否超出范围的问题而不超出其本身数据类型范围。

这样,判断一个地址串是否合法的过程就全部讲完了。接下来把上面这些部分用代码实现即可。

Code

namespace Solution {
	const int N = 1007;
	int n;
	struct node {string op, ip;}a[N];
	map<string, int> id;
	
	ib chk(string s) {
		int num = 0, fl = 0, sze = s.size(), p[27] = {0};
		string nums[7] = {""};
		s = " " + s;
		F(int, i, 1, sze) {
			if(s[i] == '.') {
				p[++num] = i;
				if(num > 3) return 0;
			} else if(s[i] == ':') {
				if(!fl) fl = i;
				else return 0;
			}
		}
		if(num < 3 || !fl) return 0;
		p[++num] = fl, p[++num] = sze;
		F(int, i, 1, num) {
			F(int, j, p[i - 1] + 1, p[i] - (i != num)) nums[i] += s[j];
			if((nums[i].size() != 1 && nums[i][0] == '0') || nums[i] == "") return 0;
			ll x = 0;
			F(int, j, 0, (int)nums[i].size() - 1) {
				x = x * 10 + nums[i][j] - '0';
				if(x > (i == num ? 65535 : 255)) return 0;
			}
		}
		return 1;
	}
	
	iv Main() {
		read(n);
		F(int, i, 1, n) {
			cin >> a[i].op >> a[i].ip;
			if(a[i].op == "Server") {
				if(!chk(a[i].ip)) puts("ERR");
				else if(id[a[i].ip]) puts("FAIL");
				else puts("OK"), id[a[i].ip] = i;
			} else {
				if(!chk(a[i].ip)) puts("ERR");
				else if(!id[a[i].ip]) puts("FAIL");
				else println(id[a[i].ip]);
			}
		}
		return;
	}
}
posted @ 2021-12-15 21:07  Eason_AC  阅读(246)  评论(0)    收藏  举报