判断掩码非法
m + (m & (-m)) || !(m + 1)
exp: 合法mask: 255.255.128.0
m = 11111111 11111111 10000000 00000000
(-m) = 00000000 00000000 10000000 00000000 (补码取反加一就是取负)
m & (-m) = 00000000 00000000 10000000 00000000 (找到最后一个1)
m + (m & (-m)) = 00000000 00000000 00000000 00000000 (如果mask合法,加最后一个1就会依次进位变为0,所以只要相加结果不为0就是非法)exp:非法mask : 128.255.255.0
m = 10000000 11111111 11111111 00000000
(-m) = 01111111 00000000 00000001 00000000
m & (-m) = 00000000 00000000 00000001 00000000
m + (m & (-m)) = 10000001 00000000 00000000 00000000 (肯定不为0,因为1之间有0,无法一直进位)exp: 特殊非法mask :255.255.255.255
m + 1 == 0 就是这种情况#include <bits stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); uint32_t p[4], p1[4], p2[4]; while (~scanf("%u.%u.%u.%u\n", p, p + 1, p + 2, p + 3)) { scanf("%u.%u.%u.%u\n", p1, p1 + 1, p1 + 2, p1 + 3); scanf("%u.%u.%u.%u\n", p2, p2 + 1, p2 + 2, p2 + 3); int8_t state = -1; uint32_t mk, ip1, ip2; int m; for (int i = 0; i < 4; i++) { if (p[i] > 255) state = 1; if (p1[i] > 255) state = 1; if (p2[i] > 255) state = 1; if (state == 1) goto nx; } for (int i = 0; i < 4; i++) { mk = (mk << 8) + p[i]; ip1 = (ip1 << 8) + p1[i]; ip2 = (ip2 << 8) + p2[i]; } m = (int)mk; if (m + (m & (-m)) || !(m + 1)) { state = 1; goto nx; } if ((mk & ip1) == (mk & ip2)) state = 0; else state = 2; nx: printf("%d\n", state); } return 0; }