题解 | #判断两个IP是否属于同一子网#
判断两个IP是否属于同一子网
http://www.nowcoder.com/practice/34a597ee15eb4fa2b956f4c595f03218
这个掩码判断合法性有点难度,我已经忘了补码了,计组太恶心了。用了bitset模板
#include <algorithm>
#include <vector>
#include <bitset>
#include <cmath>
#include <sstream>
using namespace std;
bool judgeip(const vector<string> &v){
int cnt = 0,x;
for(int i = 0;i<4;i++){
x = stoi(v[i]);
if(x>=0&&(x<=255)){
cnt++;
}
}
if(cnt==4)return true;
else return false;
}
unsigned long long mytransform(const vector<string> &v){
unsigned long long x = 0;
x+=stoi(v[0])*pow(2,24);
x+=stoi(v[1])*pow(2,16);
x+=stoi(v[2])*pow(2,8);
x+=stoi(v[3]);
return x;
}
bool judgemask(const vector<string> &v){
bool mask =false;
mask = judgeip(v);
if(!mask)return mask;
unsigned long long x= mytransform(v);
unsigned long long y =~x+1;
x=(x&(~x+1))+x;//血坑,位与运算比加法优先级低,这里找了好久的bug
bitset<32> b(x);//unsigned long long 是64位的我们只判断低32位。
if(b.count()==0)return true;
else return false;
}
int main() {
string str1,str2,str3;
while(cin>>str1>>str2>>str3){
vector<string> v1,v2,v3;
string temp;
stringstream s1,s2,s3;
s1.str(str1);
while(getline(s1,temp,'.')){
v1.push_back(temp);
}
s2.str(str2);
while(getline(s2,temp,'.')){
v2.push_back(temp);
}
s3.str(str3);
while(getline(s3,temp,'.')){
v3.push_back(temp);
}
bool samenet = false,correct = false;
correct = judgemask(v1)&&judgeip(v2)&&judgeip(v3);
if(!correct) cout<<1<<endl;
else {
unsigned long long masknet = mytransform(v1);
unsigned long long x = mytransform(v2);
unsigned long long y = mytransform(v3);
unsigned long long mx = x&masknet;
unsigned long long my = y&masknet;
if(mx==my)samenet = true;
if(samenet)cout<<0<<endl;
else cout<<2<<endl;
}
}
}