重要的是掩码连续为1然后连续为0的判断,需要位运算,准则为:
- 将掩码地址转换为32位无符号整型,假设这个数为b。如果此时b为0,则为非法掩码
- 将b按位取反后+1。如果此时b为1,则b原来是二进制全1,非法掩码
- 如果b和b-1做按位与运算后为0,则说明是合法掩码,否则为非法掩码
#include <bits/stdc++.h>
using namespace std;
vector<int> vpm;
vector<int> vpi;
vector<int> vpi2;
bool check_mask(string x) {
int i = 0;
int j = 0;
while (i < x.size() and j < x.size()) {
while (i < x.size() and !isdigit(x[i])) {
if (x[i] != '.') return false;
j = ++i;
}
while (j < x.size() and isdigit(x[j])) j++;
int tt = stoi(x.substr(i, j - i));
if (tt < 0 or tt > 255) return false;
vpm.push_back(tt);
i = ++j;
}
if (vpm.size() != 4) return false;
unsigned b = 0;
for (int x : vpm) {
b = (b << 8) + x;
}
if (b == 0) return false;
if (~b + 1 == 1) return false;
b = ~b + 1;
if ((b & (b - 1)) == 0) return true;
return false;
}
bool check_ip(string x) {
int i = 0;
int j = 0;
while (i < x.size() and j < x.size()) {
while (i < x.size() and !isdigit(x[i])) {
if (x[i] != '.') return false;
j = ++i;
}
while (j < x.size() and isdigit(x[j])) j++;
int tt = stoi(x.substr(i, j - i));
if (tt < 0 or tt > 255) return false;
vpi.push_back(tt);
i = ++j;
}
if (vpi.size() != 4) return false;
return true;
}
bool check_ip2(string x) {
int i = 0;
int j = 0;
while (i < x.size() and j < x.size()) {
while (i < x.size() and !isdigit(x[i])) {
if (x[i] != '.') return false;
j = ++i;
}
while (j < x.size() and isdigit(x[j])) j++;
int tt = stoi(x.substr(i, j - i));
if (tt < 0 or tt > 255) return false;
vpi2.push_back(tt);
i = ++j;
}
if (vpi2.size() != 4) return false;
return true;
}
int main() {
string c, a, b;
while (cin >> c >> a >> b) { // 注意 while 处理多个 case
vpi.clear();
vpm.clear();
vpi2.clear();
if (check_mask(c) and check_ip(a) and check_ip2(b)) {
bool flag = true;
for(int i = 0; i < 4; i++){
if((vpm[i] & vpi[i]) != (vpm[i] &vpi2[i])){
flag = false;
break;
}
}
if (flag) cout << "0" << endl;
else cout << "2" << endl;
}
else cout << "1" << endl;
}
return 0;
}
// 64 位输出请用 printf("%lld")

京公网安备 11010502036488号