微软2016校招4月在线笔试——第二题 403Forbidden
来源:互联网 发布:miss7号淘宝店 编辑:程序博客网 时间:2024/05/17 09:42
http://hihocoder.com/problemset/problem/1289
↑↑↑ 题目原址
- 样例输入
5 5allow 1.2.3.4/30deny 1.1.1.1allow 127.0.0.1allow 123.234.12.23/3deny 0.0.0.0/01.2.3.41.2.3.51.1.1.1100.100.100.100219.142.53.100
- 样例输出
YESYESNOYESNO
描述
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/30deny 1.1.1.1allow 127.0.0.1allow 123.234.12.23/3deny 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.
思路:
定义结构体IPStruct { int first, second, third, forth, mask}, 其中所有初始值为0
分别提取rules进入allowrules数组和denyrules数组,
这里应该是有比较好的写法的,由于平时没怎么写过,所以只能靠纯手写最土的方法转换了。
在gets(rules[i])的过程中就判断,如果rules[i][0] == 'a',则 allowcnt++;否则,denycnt++;
gets完所有rules之后,初始化 1个容量为allowcnt 的 IPStruct 数组 allowrules, 再初始化一个容量为 denycnt 的 IPStruc t数组 denyrules。
分别提取rules进入两个数组,如果有‘/', 则 this.mask = '/'后面的数组转int; 否则 mask = -1。
然后提取request进入一个容量为M的IPStruct 数组
遍历两组rules进行match。
先遍历allowrules,若有符合,直接输出YES,continue入下一request;
若无allowrules match,则遍历denyrules,若matched,直接输出NO,continue入下一request;
若无matched,输出YES,continue入下一request。
match的过程是这样的。allow和deny的思路一样,只是输出为true和false的区别。以下以allow为例。
拿到一个request,首先进行遍历allowrules。
首先判断allowrules[i].mask != -1?,
{
若不等于,则代表含掩码
判断 rules[i] 是否 contain request。
是,返回 true。
否则
否,判断 判断allowrules[i]与request是否相等(isequal)。
是,返回 true。
否则
continue进入下一allowrules, i++
}
else
{
如果等于,则
判断allowrules[i]与request是否相等(isequal)。
是,返回 true。
否则
continue 进入下一 allowrules
}
同样 的结构遍历判断 deny rules, 是则返回false,不是则continue进入下一denyrules。
若能走到这里仍然未return,则return true(没有任何规则匹配,则允许)。
判断是否contain的思路是这样的。分别以<9,<17,<25,<33为界
if mask < 9
if ( a.first >> (8 - a.mask) == b.first >> (8 - a.mask) )
return true;
else
return false;
else if mask < 17
if (a.first != b.first)
return false;
else if ( a.second >> (16 - a. mask) == b.second >> (16 - a.mask) )
return true;
else
return false;
else if mask < 25
if (a.first != b.first || a.sencond != b.second)
return false;
else if .........
....
...
题目中的testcase是能够正确输出的,但是提交后为WA,不知道是哪种情况未考虑到呢。。。
另有其他更好的算法,希望能不吝赐教~~
#include <iostream>#include <string>using namespace std;struct IPstruct{int sfirst,ssecond,sthird,sforth;int mask;};IPstruct getRules(char* s);IPstruct GetIPs(char* s);bool Match(IPstruct req, IPstruct *denied, IPstruct *allowed, int deniedcnt, int allowcnt);bool validchar(char c){if (c == '.' || c == '/'){return true;}else if (c >= '0' && c <= '9'){return true;}elsereturn false;}IPstruct getRules(char *s){IPstruct newIP;newIP.sfirst = 0;newIP.ssecond = 0;newIP.sthird = 0;newIP.sforth = 0;newIP.mask = 0;if (s[0] == 'd'){int i = 5;for (; validchar(s[i]) && s[i] != '.'; i++){newIP.sfirst = newIP.sfirst*10 + s[i] - '0';}for (i++; s[i] != '.'; i++){newIP.ssecond = newIP.ssecond*10 + s[i] - '0';}for (i++; s[i] != '.'; i++){newIP.sthird = newIP.sthird*10 + s[i] - '0';}for (i++; validchar(s[i]) && s[i] != '/'; i++){newIP.sforth = newIP.sforth * 10 + s[i] - '0';}if (s[i] == '/'){for (i++; validchar(s[i]); i++)newIP.mask = newIP.mask * 10 + s[i] - '0';}else{newIP.mask = -1;}}else{int i = 6;for (; validchar(s[i]) && s[i] != '.'; i++){newIP.sfirst = newIP.sfirst*10 + s[i] - '0';}for (i++; s[i] != '.'; i++){newIP.ssecond = newIP.ssecond*10 + s[i] - '0';}for (i++; s[i] != '.'; i++){newIP.sthird = newIP.sthird*10 + s[i] - '0';}for (i++; validchar(s[i]) && s[i] != '/'; i++){newIP.sforth = newIP.sforth * 10 + s[i] - '0';}if (s[i] == '/'){for (i++; validchar(s[i]); i++)newIP.mask = newIP.mask * 10 + s[i] - '0';}else{newIP.mask = -1;}}return newIP;}IPstruct GetIPs(char* s){IPstruct newIP;newIP.sfirst = 0;newIP.ssecond = 0;newIP.sthird = 0;newIP.sforth = 0;newIP.mask = 0;int i = 0;for (; validchar(s[i]) && s[i] != '.'; i++){newIP.sfirst = newIP.sfirst*10 + s[i] - '0';}for (i++; s[i] != '.'; i++){newIP.ssecond = newIP.ssecond*10 + s[i] - '0';}for (i++; s[i] != '.'; i++){newIP.sthird = newIP.sthird*10 + s[i] - '0';}for (i++; validchar(s[i]) && s[i] != '/'; i++){newIP.sforth = newIP.sforth * 10 + s[i] - '0';}if (s[i] == '/'){for (i++; validchar(s[i]); i++)newIP.mask = newIP.mask * 10 + s[i] - '0';}else{newIP.mask = -1;}return newIP;}bool isequal(const IPstruct& a, const IPstruct& b){if (a.sfirst == b.sfirst && a.ssecond == b.ssecond && a.sthird == b.sthird && a.sforth == b.sforth)return true;elsereturn false;}bool iscontain(const IPstruct& a, const IPstruct& b){if (a.mask < 9){if( (a.sfirst >> (8 - a.mask)) == (b.sfirst >> (8 - a.mask)) )return true;else return false;}else if (a.mask < 17){if (a.sfirst != b.sfirst){return false;}else if ( (a.ssecond >> (16 - a.mask)) == (b.ssecond >> (16 - a.mask)) ){return true;}elsereturn false;}else if (a.mask < 25){if (a.sfirst != b.sfirst || a.ssecond != b.ssecond){return false;}else if ( (a.sthird >> (24 - a.mask)) == (b.sthird >> (24 - a.mask)) ){return true;}elsereturn false;}else if (a.mask < 33){if ( a.sfirst != b.sfirst || a.ssecond != b.ssecond || a.sthird != b.sthird){return false;}else if ( (a.sforth >> (32 - a.mask)) == (b.sforth >> (32-a.mask)) ){return true;}elsereturn false;}else{return false;}}bool Match(IPstruct req, IPstruct *denied, IPstruct *allowed, int deniedcnt, int allowcnt){for (int i = 0; i < allowcnt; i++){if (allowed[i].mask != -1){if (iscontain(allowed[i], req)){return true;}else if (isequal(req, allowed[i])){return true;}elsecontinue;}else{if (isequal(req, allowed[i])){return true;}}}for (int i = 0; i < deniedcnt; i++){if (denied[i].mask != -1){if (iscontain(denied[i], req)){return false;}else if (isequal(req, denied[i])){return false;}elsecontinue;}else{if (isequal(req, denied[i])){return false;}}}return true;}int main(){int N, M;int deniedcnt = 0, allowcnt = 0;cin >> N >> M;char **rules, **request;rules = new char* [N];request = new char* [M];char *t = new char[2];gets(t);for (int i = 0; i < N; i++){rules[i] = new char [256];gets(rules[i]);if (rules[i][0] == 'd'){deniedcnt++;}else{allowcnt++;}}IPstruct *denied = new IPstruct [deniedcnt];IPstruct *allowed = new IPstruct [allowcnt];for (int j = 0; j < M; j++){request[j] = new char [256];gets(request[j]);}int deniedindex = 0, allowindex = 0;for (int i = 0; i < N; i++){if (rules[i][0] == 'd'){denied[deniedindex++] = getRules(rules[i]);}else{allowed[allowindex++] = getRules(rules[i]);}}for (int i = 0; i < M; i++){if (Match(GetIPs(request[i]), denied, allowed, deniedcnt, allowcnt)){cout << "YES" << endl;}else{cout << "NO" << endl;}}return 0;}
)
- 微软2016校招4月在线笔试——第二题 403Forbidden
- 2016年4月微软在线笔试第二题-403 forbidden
- 微软2016校招4月在线笔试——第一题 Font Size
- 微软2016校园招聘4月在线笔试2-403 Forbidden
- 微软2016校园招聘4月在线笔试 hihocoder 1289 403 Forbidden
- [Hihocoder 1289] 403 Forbidden (微软2016校园招聘4月在线笔试)
- hihocoder 1289 微软2016校园招聘4月在线笔试-2:403 Forbidden
- 微软2016校园招聘4月在线笔试2-403 Forbidden
- 微软2016年实习生在线笔试第二题(403 Forbidden)
- 微软2016实习生笔试--第二题403 Forbidden
- 微软2017实习生在线笔试题——hihocoder 1289——403 Forbidden
- 微软苏州校招1月3日在线编程题1——constellations
- 微软苏州校招1月3日在线编程题2——Disk Storage
- 微软2016校园招聘4月在线笔试题
- 2016微软在线编程2:403 Forbidden
- 【hihocoder】1237 : Farthest Point ->微软2016校招在线笔试题
- 微软笔试题2:403 Forbidden
- 微软2016校招笔试题
- 贪心算法 problemD
- 创建Filter类
- iso中第三方框架SDWebImage的使用步骤
- Python字符串
- 01-Memcached介绍
- 微软2016校招4月在线笔试——第二题 403Forbidden
- Docker问题(Get http:///var/run/docker.sock/v1.20/version:dial unix /var/run/docker.sock: no such file)
- 3.8 postfix字符串与流
- 生成螺旋矩阵(方阵、矩阵)
- 匿名内部类
- android开发判断手机网络连接状态
- 主流操作系统、浏览器DNS缓存时间
- 3.8.1 VBUF, VSTRING和VSTREAM结构体
- MSDE 2000