思路

恶心的模拟题。

但是比起这题这题就好多了……

唯一要注意的只有一点:把 IP 转换成数字时,可能会很大,但是 2525 位减去三个 .,一个 :,四个 0,刚好剩 1818 位,long long 刚好能存!!!

而且,原本需要用 map 或哈希表优化查找过程,可是这个 n103n \le 10^3,可以直接 O(n2)O(n^2) 查找。

代码

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <string>

using namespace std;

int n, cnt;
string op[1001], ad[1001];
long long toint(string s){ // 转换为数字
	long long x = 0;
	for (int i = 0;i < s.size();i ++) x = x * 10 + (s[i] - '0');
	return x;
}
bool check(string s){
	int i, x;
	long long num;
	for (i = 0, x = 0;;){
		if (i >= s.size()) return 0; // 不够读
		string nums;
		bool read = 0;
		while ('0' <= s[i] && s[i] <= '9'){
			read = 1; // 读到了
			nums += s[i ++];
			if (i >= s.size()) return 0; // 不够读
		}
		num = toint(nums); // 转换
		if (((nums[0] == '0' && num > 0) || (num == 0 && nums.size() > 1)) || !read) return 0; // 没读到或前导 0
		x ++;
		if (num > 255 || num < 0) return 0; // 超出范围
		if (x == 4) break; // 读够了
		if (s[i ++] != '.') return 0; // 符号不对
	}
	if (s[i ++] != ':') return 0; // 符号不对
	if (i >= s.size()) return 0; // 不够读
	string nums;
	bool read = 0;
	while ('0' <= s[i] && s[i] <= '9'){
		read = 1;
		nums += s[i ++];
		if (i >= s.size()) break;
	}
	num = toint(nums);
	if (((nums[0] == '0' && num > 0) || (num == 0 && nums.size() > 1)) || !read) return 0;
	if (num > 65535 || num < 0) return 0; // 同上
	return 1; // 终于通过了……
}
int main(){
	cin >> n;
	for (int i = 1;i <= n;i ++){
		cin >> op[i] >> ad[i];
		if (!check(ad[i])) cout << "ERR" << endl; // 不合法
		else {
			if (op[i] == "Server"){
				bool flg = 1;
				for (int j = 1;j < i;j ++){ // 暴力查找
					if (op[j] == "Server" && ad[j] == ad[i]){ // 有相同
						flg = 0;
						cout << "FAIL" << endl;
						break;
					}
				}
				if (flg) cout << "OK" << endl; // OK
			}
			else {
				bool flg = 1;
				for (int j = 1;j < i;j ++){
					if (op[j] == "Server" && ad[j] == ad[i]){ // 连接成功
						flg = 0;
						cout << j << endl;
						break;
					}
				}
				if (flg) cout << "FAIL" << endl; // 失败
			}
		}
	}
}