描述
Little Hi runs a web server. Sometimes he has to deny access from a certain set of malicious IP addresses while his friends are still allow to access his server. To do this he writes N rules in the configuration file which look like:
allow 1.2.3.4/30 deny 1.1.1.1 allow 127.0.0.1 allow 123.234.12.23/3 deny 0.0.0.0/0
Each rule is in the form: allow | deny address or allow | deny address/mask.
When there comes a request, the rules are checked in sequence until the first match is found. If no rule is matched the request will be allowed. Rule and request are matched if the request address is the same as the rule address or they share the same first mask digits when both written as 32bit binary number.
For example IP "1.2.3.4" matches rule "allow 1.2.3.4" because the addresses are the same. And IP "128.127.8.125" matches rule "deny 128.127.4.100/20" because 10000000011111110000010001100100 (128.127.4.100 as binary number) shares the first 20 (mask) digits with10000000011111110000100001111101 (128.127.8.125 as binary number).
Now comes M access requests. Given their IP addresses, your task is to find out which ones are allowed and which ones are denied.
输入
Line 1: two integers N and M.
Line 2-N+1: one rule on each line.
Line N+2-N+M+1: one IP address on each line.
All addresses are IPv4 addresses(0.0.0.0 - 255.255.255.255). 0 <= mask <= 32.
For 40% of the data: 1 <= N, M <= 1000.
For 100% of the data: 1 <= N, M <= 100000.
输出
For each request output "YES" or "NO" according to whether it is allowed.
5 5 allow 1.2.3.4/30 deny 1.1.1.1 allow 127.0.0.1 allow 123.234.12.23/3 deny 0.0.0.0/0 1.2.3.4 1.2.3.5 1.1.1.1 100.100.100.100 219.142.53.100
YES YES NO YES NO
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
struct sRules{
bool access;
unsigned int mask;
unsigned int IP;
};
int main()
{
string outstr[2]={"NO","YES"};
int N,M;
cin >> N >> M;
sRules* Rule = new sRules[N];
string InputTemp;
unsigned int d0,d1,d2,d3,mask,TempIP;
for(int i=0;i<N;i++){
InputTemp="";
cin >> InputTemp;
Rule[i].access=(InputTemp=="allow");
InputTemp="";
cin >> InputTemp;
if(sscanf(InputTemp.c_str(),"%d.%d.%d.%d/%d",&d0,&d1,&d2,&d3,&mask)==5){
//cout << hex << mask << endl;
Rule[i].mask=(mask==0)?0:(((0xFFFFFFFF)>>(32-mask))<<(32-mask));
//cout << hex << Rule[i].mask << endl;
}
else
Rule[i].mask=0xFFFFFFFF;
Rule[i].IP=(d0<<24)|(d1<<16)|(d2<<8)|(d3);
}
for(int i=0;i<M;i++){
InputTemp="";
cin >> InputTemp;
sscanf(InputTemp.c_str(),"%d.%d.%d.%d",&d0,&d1,&d2,&d3);
TempIP=(d0<<24)|(d1<<16)|(d2<<8)|(d3);
bool flag = 0;
for(int j=0;j<N;j++){
if((TempIP&Rule[j].mask)==(Rule[j].IP&Rule[j].mask)){
cout << outstr[Rule[j].access] << endl;
flag = 1;
break;
}
}
if(!flag)
cout << "out" << endl;
}
return 0;
}
最后才调出来,案例数据测试正确,不知道系统下能不能过,总结下自己这次调不出来的很low的问题:
1. 32位整型掩码,当时顺手就直接写的0xFFFF显然不对,改成0xFFFFFFFF
2. 再就是忘了无符号整型的减法问题了-->像
Rule[i].mask=(mask==0)?0:(((0xFFFFFFFF)>>(32-mask))<<(32-mask));
这一部分,mask我定义成了无符号整型
unsigned int i=0;
cout << (0xFFFFFFFF>>(32-i)<<(32-i)) << endl; //0Xffffffff //不懂为嘛?????? release版本下就是0了,好神奇
cout << (0xFFFFFFFF>>(unsigned int)32<<(unsigned int)32) << endl; //0
cout << (unsigned int)32 << endl; //32
cout << (0xFFFFFFFF>>32<<32) << endl; //0
codeblocks、VC编译运行得出的结果,但是可以看出这里输出不是预期的结果,比较渣还不明白为啥不对。如果有人看了还懂,欢迎留言解释下
不过总结教训,无符号整数的减法一定要注意(以后尽量不去用这个吧),0XFF这些一定要注意位数正确