微软2016实习生笔试--第二题403 Forbidden

2024-06-03 14:18

本文主要是介绍微软2016实习生笔试--第二题403 Forbidden,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

#1289 : 403 Forbidden

时间限制: 10000ms
单点时限: 1000ms
内存限制: 256MB

描述

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

由题意直观的可以想到以下做法:

  1. 设计一个结构体,描述配置规则;
  2. 按读入顺序保存读入的所有规则;
  3. 对于每一个待检验的IP,从头遍历规则,若匹配,返回规则的动作;否则,返回允许
代码如下
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <vector>
using namespace std;struct Rule           // 存放规则的结构体
{bool allow;unsigned int ip;int mask;Rule() : allow(false), ip(0), mask(32){}
};unsigned int getIp()   // 获得输入的IP地址
{unsigned int a, b, c, d;char dot;cin >> a >> dot >> b >> dot >> c >> dot >> d;return (a << 24) | (b << 16) | (c << 8) | d;
}bool solve(vector<Rule> &rules, unsigned int ip)   // 判断IP地址满足的规则
{for(auto rule : rules){if(rule.mask == 0 || (ip ^ rule.ip) >> (32-rule.mask) == 0)return rule.allow;}return true;
}int main()
{int N, M;while(cin >> N >> M){char cmd[20];char t;vector<Rule> rules(N);for(int i = 0; i < N; i++){cin >> cmd;rules[i].allow = strcmp(cmd, "allow") == 0;rules[i].ip = getIp();cin.get(t);if(t == '/')cin >> rules[i].mask;elsecin.putback(t);}bool* result = new bool[M];for(int j = 0; j < M; j++){unsigned int ip = getIp();result[j] = solve(rules, ip);}for(int i = 0; i < M; i++)cout << (result[i] ? "Yes" : "No" )<<endl;delete[] result;}return 0;
}

前缀匹配问题,可以用前缀树来解决。因此,可以利用前缀树来确定哪些规则可以适用于一个IP。

Trie Approach

于是有了下面的想法:

  1. 规则集利用前缀树描述
  2. 前缀树每个结点记录,到本结点是否为一个规则,规则要求的动作是什么,规则的序号。
  3. 对于一个IP,遍历前缀树,找到所适用规则中序号最小的,返回该规则的要求,若没有适用规则,返回允许。
  4. 一个IPv4的地址大小为32bit,也就是可以在常量时间找到适用规则。

至此,剩下的问题就是如果建立前缀树,由于题意要求,最早匹配原则,树的建立可以这样做:

  1. 若插入新规则i时,该规则的前缀路径上已有规则j, 则规则j的序号一定比i小,也即,规则i被j屏蔽,直接丢弃i即可。
  2. 注意第一条中,当规则i和j等长时,也适用。
代码如下
#include <iostream>
#include <cstring>using namespace std;class Trie     // 建立规则集的前缀树
{
private:struct TrieNode   // 前缀树节点{int order;   // 定义规则的序号TrieNode* children[2];   // 连接下一前缀树节点TrieNode() : order(0){children[0] = children[1] = NULL;}};TrieNode *root;
public:Trie() : root(new TrieNode()){}void addRule(unsigned int ip, int mask, int order)  // 添加规则{TrieNode* pos = root;for(int i = 1; i <= mask; i++){if(pos->order)    // 当前缀路径上已有规则时,直接返回,丢弃当前要插入的规则return;int bit = (ip >> (32-i)) & 1;if(!(pos->children[bit])){TrieNode* newNode = new TrieNode();pos->children[bit] = newNode;}pos = pos->children[bit];}if(!(pos->order))pos->order = order;}int query(unsigned int ip)   // 查询ip满足的规则{TrieNode *pos = root;int order = 1;for(int i = 1; i <= 32; i++){if(pos->order)order = pos->order;int bit = (ip >> (32-i)) & 1;if(!(pos->children[bit]))break;pos = pos->children[bit];}return order;}
};inline unsigned int getIp()  // 得到输入的IP
{unsigned int a, b, c, d;char dot;cin >> a >> dot >> b >> dot >> c >> dot >> d;return (a << 24) | (b << 16) | (c << 8) | d;
}int main()
{int N, M;Trie rule;while(cin >> N >> M){char cmd[20];char t;for(int i = 1; i <= N; i++){int mask = 32;cin >> cmd;unsigned int ip = getIp();cin.get(t);if(t == '/')cin >> mask;elsecin.putback(t);int order = i;if(strcmp(cmd, "allow"))order *= -1;rule.addRule(ip, mask, order);}int *result = new int[M];for(int j = 0; j < M; j++){unsigned int ip = getIp();result[j] = rule.query(ip);}for(int i = 0; i < M; i++)cout << (result[i] > 0 ? "Yes" : "No") <<endl;delete[] result;}return 0;
}



这篇关于微软2016实习生笔试--第二题403 Forbidden的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1027221

相关文章

闲置电脑也能活出第二春?鲁大师AiNAS让你动动手指就能轻松部署

对于大多数人而言,在这个“数据爆炸”的时代或多或少都遇到过存储告急的情况,这使得“存储焦虑”不再是个别现象,而将会是随着软件的不断臃肿而越来越普遍的情况。从不少手机厂商都开始将存储上限提升至1TB可以见得,我们似乎正处在互联网信息飞速增长的阶段,对于存储的需求也将会不断扩大。对于苹果用户而言,这一问题愈发严峻,毕竟512GB和1TB版本的iPhone可不是人人都消费得起的,因此成熟的外置存储方案开

《数据结构(C语言版)第二版》第八章-排序(8.3-交换排序、8.4-选择排序)

8.3 交换排序 8.3.1 冒泡排序 【算法特点】 (1) 稳定排序。 (2) 可用于链式存储结构。 (3) 移动记录次数较多,算法平均时间性能比直接插入排序差。当初始记录无序,n较大时, 此算法不宜采用。 #include <stdio.h>#include <stdlib.h>#define MAXSIZE 26typedef int KeyType;typedef char In

CSP 2023 提高级第一轮 CSP-S 2023初试题 完善程序第二题解析 未完

一、题目阅读 (最大值之和)给定整数序列 a0,⋯,an−1,求该序列所有非空连续子序列的最大值之和。上述参数满足 1≤n≤105 和 1≤ai≤108。 一个序列的非空连续子序列可以用两个下标 ll 和 rr(其中0≤l≤r<n0≤l≤r<n)表示,对应的序列为 al,al+1,⋯,ar​。两个非空连续子序列不同,当且仅当下标不同。 例如,当原序列为 [1,2,1,2] 时,要计算子序列 [

微软正式推出 Spartan 斯巴达浏览器

作为用于替代 IE 浏览器的下一代继任者,微软的 Project Spartan 斯巴达浏览器可算是吊足了玩家们的胃口!如今,在最新的 Windows 10 Build 10049 版本起,它终于正式登场了。 斯巴达浏览器搭载了全新的渲染引擎、新的用户界面并集成了 Cortana 语音助手。功能上新增了稍后阅读列表、阅读视图、F12开发者工具、支持网页注释 (手写涂鸦),可以保存到 O

【秋招笔试】9.07米哈游秋招改编题-三语言题解

🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 大厂实习经历 ✨ 本系列打算持续跟新 春秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 🍒 本专栏已收集 100+ 套笔试题,笔试真题 会在第一时间跟新 🍄 题面描述等均已改编,如果和你笔试题看到的题面描述

两道笔试题

“char a='\72'”是什么意思? 这么理解:\为转义字符,\072转义为一个八进制数072,也就是十进制数的58买一送一,将转义字符对照表也一并贴给你吧:转义字符 意义 ASCII码值(十进制) \a 响铃(BEL) 007 \b 退格(BS) 008 \f 换页(FF) 012 \n 换行(LF) 010 \r 回车(CR) 013 \t 水平制表(HT) 009 \v 垂直制表(VT

华为23年笔试题

消息传输 题目描述 在给定的 m x n (1 <= m, n <= 1000) 网格地图 grid 中,分布着一些信号塔,用于区域间通信。 每个单元格可以有以下三种状态:  值 0 代表空地,无法传递信号;  值 1 代表信号塔 A,在收到消息后,信号塔 A 可以在 1ms 后将信号发送给上下左右四个方向的信号塔; 值 2 代表信号塔 B,在收到消息后,信号塔 B 可以在 2ms

实现的动态规划问题华为笔试题C++实现

秋招刷力扣题,我觉得我对动态规划不是熟练,在此处做总结 动态规划(Dynamic Programming,DP)算法通常用于求解某种具有最优性质的问题。在这类问题中,可能会有许多可行解,每一个解都对应一个值,我们希望找到具有最优值的解。我觉得最大的问题就是对问题的分解,分解后的问题与分解前的问题具有相同的决策机制,将决策机制进行抽象,最终可以得到对应的解; 动态规划中开始介绍的爬楼梯等问题,答

某公司笔试编程题

参加了某公司编程题,这些题都来自牛客网,记录总结吧! 一、蛇形矩阵 题目描述 蛇形矩阵是有1开始的自然数依次排列成的一个上三角矩阵. 接口说明 void GetResult(int Num, int* pResult);输入参数:int Num :输入的正整数N输出参数:int *pResult: 指向放蛇形矩阵的字符串指针指针指向的内存区域保证有效 样例输入: 4