本题涉及很多字符串的处理,进制转换的处理,以及IP地址和子网掩码的判别问题,综合性较强。
# include <iostream>
# include <string>
# include <vector>
# include <sstream>
# include <cmath>
using namespace std; 

// 用于分割地址中各段的字符串
vector<string> get_string(string s) {
    istringstream is(s);
    string seg;
    vector<string> res;
    while (getline(is, seg, '.')) {
        res.push_back(seg);
    }
    return res;
}

// 判断IP地址是否合法
bool judge_IP(string s) {
    vector<string> IP = get_string(s);
    int k = 0;
    for (vector<string>::iterator iter = IP.begin(); iter != IP.end(); iter++) {
        auto seg = *iter;
        k++;
        if (seg == " ") return false;
        else {
            if (stoi(seg) > 255) return false;
            if (stoi(seg) < 0) return false;
        }
    }
    if (k == 4) return true;
    else return false;
}

// 判断子网掩码地址是否合法
bool judge_mask(string s) {
    vector<string> mask = get_string(s);
    unsigned b = 0;
    for (vector<string>::iterator iter = mask.begin(); iter != mask.end(); iter++) {
        auto seg = *iter;
        if (seg == " ") return false;
        else {
            // 将子网掩码地址转换为32位无符号整形
            b = (b << 8) + stoi(seg);
        }
    }
    if (!b) {
        return false;  // b为零,非法
    }
    b = ~b + 1;
    if (b == 1) {
        return false;  // b按位取反后加一,如果此时b为1,则b原来是二进制全一,非法
    }
    if ((b & (b - 1)) == 0) {
        return true;  // b和b-1按位运算后为0,合法
    }
    return false;
}

// 将十进制转换为二进制
vector<string> dec_bin(vector<string> dec) {
    vector<string> res;
    for (vector<string>::iterator iter = dec.begin(); iter != dec.end(); iter++) {
        int val = stoi(*iter);
        string s;
        int rem = val % 2;
        val /= 2;
        s = s + to_string(rem);
        while (val != 0) {
            rem = val % 2;
            val /= 2;
            s = s + to_string(rem);
        }
        string s_reverse;
        if (s.size() != 8) {
            // 不足8位
            int num = 8 - s.size();
            for (int k = 0; k < num; k++) {
                s_reverse = s_reverse + "0";
            }
        }
        for (int j = s.size() - 1; j >= 0; j--) {
            s_reverse = s_reverse + s[j];
        }
        res.push_back(s_reverse);
    }
    return res;
}

//将二进制转换为十进制
vector<int> bin_dec(vector<string> s) {
    vector<int> dec;
    int sum = 0;
    for (vector<string>::iterator iter = s.begin(); iter != s.end(); iter++) {
        string temp = *iter;
        for(int i = temp.size() - 1; i >= 0; i--) {
            sum += stoi(string(1, temp[i])) * pow(2, temp.size() - 1 - i);
        }
        dec.push_back(sum);
        sum = 0;
    }
    return dec;
}

// 判断两个IP地址是否在同一个子网中
bool judge_IP_isSame(string mask, string IP1, string IP2) {
    vector<string> v_mask_temp = get_string(mask);
    vector<string> v_IP1_temp = get_string(IP1);
    vector<string> v_IP2_temp = get_string(IP2);
    // 将十进制转换为二进制
    vector<string> v_mask = dec_bin(v_mask_temp);
    vector<string> v_IP1 = dec_bin(v_IP1_temp);
    vector<string> v_IP2 = dec_bin(v_IP2_temp);
    // 合成二进制
    string mask_bin, IP1_bin, IP2_bin;
    for (int i = 0; i < 4; i++) {
        mask_bin = mask_bin + v_mask[i];
        IP1_bin = IP1_bin + v_IP1[i];
        IP2_bin = IP2_bin + v_IP2[i];
    }
    // 两个二进制取与操作
    string AND1, AND2;
    for (int i = 0; i < 32; i++) {
        if (mask_bin[i] == '1' && IP1_bin[i] == '1') AND1 = AND1 + "1";
        else AND1 = AND1 + "0";
        if (mask_bin[i] == '1' && IP2_bin[i] == '1') AND2 = AND2 + "1";
        else AND2 = AND2 + "0";
    }
    // 拆分为四段字符串
    vector<string> AND1_seg, AND2_seg;
    for (int i = 0; i < 4; i++) {
        AND1_seg.push_back(AND1.substr(i * 8, 8));
        AND2_seg.push_back(AND2.substr(i * 8, 8));
    }
    // 二进制转换为十进制(这一步其实不用转换,直接比较二进制就可以了)
    vector<int> AND1_dec, AND2_dec;
    AND1_dec = bin_dec(AND1_seg);
    AND2_dec = bin_dec(AND2_seg);
    // 判断是否相等
    for (int i = 0; i < 4; i++) {
        if (AND1_dec[i] != AND2_dec[i]) return false;
    }
    return true;
}


int main(){
    string mask, IP1, IP2;
    getline(cin, mask, '\n');
    getline(cin, IP1, '\n');
    getline(cin, IP2, '\n');
    // 判断地址是否非法
    if (!judge_mask(mask) || !judge_IP(IP1) || !judge_IP(IP2)) {
        cout << "1" << endl;
    } else {
        if (judge_IP_isSame(mask, IP1, IP2)) {
            // 两个IP属于同一个网络
            cout << "0" << endl;
        } else {
            // 两个IP不属于同一个网络
            cout << "2" << endl;
        }
    }
    return 0;
}