CSP-2021 T3 网络连接 题解

· · 题解

我爱大模拟!

其实这道题就是细心一点就能过,考场上给的大样例非常友好,我就是靠它一个一个找出错误然后修改的...最后没想到满分了

一些关键点:

解决方案:

可以使用一些字符串库函数来简化代码。

下面奉上原汁原味的考场代码,具体注释都在里面:

#include <bits/stdc++.h>
using namespace std;
int n;
// 判断前导零
bool checkPrevZero(const string number) {
    // 单独一个 0 是不算非法的。
    if (number.length() > 1 && number[0] == '0') return true;
    return false;
}
// string 转 int
int strToInt(const string number) {
    int t = 0;
    for (int i = 0; i < number.length(); i++) {
        t *= 10;
        t += number[i]-'0';
    }
    return t;
}
bool check(const string addr) {
    int cntDot = 0, cntMao = 0; // 点的出现次数和冒号的出现次数
    int dotIdx[3], maoIdx;  // 点出现的位置和冒号出现的位置
    if (!(addr[0] >= '0' && addr[0] <= '9') || !(addr[addr.length()-1] >= '0' && addr[addr.length()-1] <= '9')) return false;
    for (int i = 0; i < addr.length(); i++) {
        if (addr[i] == '.') {
            if (cntDot > 2) return false;  // 多于三个点
            if (!(addr[i-1] >= '0' && addr[i-1] <= '9')) return false;
            cntDot++;
            dotIdx[cntDot-1] = i;
        } else if (addr[i] == ':') {
            if (cntMao > 1) return false; // 多于一个冒号
            if (!(addr[i-1] >= '0' && addr[i-1] <= '9')) return false;
            cntMao++;
            maoIdx = i;
        } else if (!(addr[i] >= '0' && addr[i] <= '9')) { // 啥也不是
            return false;
        }
    }
    if (!(cntDot == 3 && cntMao == 1)) return false; // 检查点和冒号的数量
    if (maoIdx < dotIdx[2]) return false; // 如果冒号的位置在某一个点前面
   // 分离出五个数字
    string n1 = addr.substr(0, dotIdx[0]),
           n2 = addr.substr(dotIdx[0]+1, dotIdx[1]-dotIdx[0]-1),
           n3 = addr.substr(dotIdx[1]+1, dotIdx[2]-dotIdx[1]-1),
           n4 = addr.substr(dotIdx[2]+1, maoIdx-dotIdx[2]-1),
           n5 = addr.substr(maoIdx+1, addr.length()-maoIdx-1);

    if (checkPrevZero(n1) || checkPrevZero(n2) || checkPrevZero(n3) || checkPrevZero(n4) || checkPrevZero(n5)) return false; // 判断前导零
    if (n1.length() > 3 || n2.length() > 3 || n3.length() > 3 || n4.length() > 3 || n5.length() > 5) return false;  // 判断越界
    int a = strToInt(n1), b = strToInt(n2), c = strToInt(n3), d = strToInt(n4), e = strToInt(n5);
    if (a > 255 || b > 255 || c > 255 || d > 255 || e > 65535) return false;  // 判断越界
    return true;
}
int serversNum = 0;
map<string, int> servers;
int main()
{
    cin >> n;
    string op, ad;
    for (int i = 0; i < n; i++) {
        cin >> op >> ad;
        if (!check(ad)) {
            cout << "ERR\n";
            continue;
        }
        if (op == "Server") {
            if (servers[ad] != 0) {
                cout << "FAIL\n";
                continue;
            }
            servers[ad] = i+1;
            cout << "OK\n";
        } else if (op == "Client") {
            if (servers[ad] == 0) {
                cout << "FAIL\n";
                continue;
            }
            cout << servers[ad] << endl;
        }
    }
    return 0;
}