hihoCoder 403 Forbidden 字典树
题意:给定个规则,个ip,问这些ip是否能和某个规则匹配,如果有多个规则,则匹配第一个。如果没能匹配成功,则认为是”allow”,否则根据规则决定是”allow”或者”deny”.
思路:字典树,将所有ip全部转换为01串,在字典树上面插入查找。
在求二进制时,注意补前缀0。
坑点:
1.字典树上每一个规则都应该带一个序号,表示这是第几个规则,因为题目要求第一个匹配,那么当你利用ip去寻找匹配的规则时,应该是找到序号最小的。
2.出现deny 0.0.0.0/0,说明所有无法匹配ip的都是deny,因为这些ip和这条规则匹配。
给大家贴几个测试数据:
5 2
deny 0.0.0.0/0
allow 0.0.0.0/0
deny 0.0.0.0/1
deny 0.0.0.0/2
allow 123.234.12.23/3
123.234.12.23
0.234.12.23
答案: NO NO
2 1
deny 1.1.1.1
allow 127.0.0.1
1.1.1.222
答案:YES
AC代码
#include <cstdio>
#include <cmath>
#include <cctype>
#include <bitset>
#include <algorithm>
#include <cstring>
#include <utility>
#include <string>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define eps 1e-10
#define inf 0x3f3f3f3f
#define PI pair<int, int>
typedef long long LL;
const int maxn = 1e5 + 5;
bool is_zero, tag;
struct node{
int ok, order;
node *nex[2];
node() {
ok = -1; //从未访问过
nex[0] = nex[1] = NULL;
}
}*root;
void init() {
root = new node();
}
void insert(string &s, int n, int ok, int order) {
node *p = root, *q;
for(int i = 0; i < n; ++i) {
int u = s[i] - '0';
if(p->nex[u] == NULL) {
q = new node();
p->nex[u] = q;
}
p = p->nex[u];
if(i == n-1 && p->ok == -1) {
p->ok = ok;
p->order = order;
}
}
}
bool search(string &s) {
node *p = root;
bool ok = true;
int order = inf;
for(int i = 0; i < s.size(); ++i) {
int u = s[i]-'0';
if(p->nex[u] == NULL) break;
else {
if(p->nex[u]->ok != -1 && p->nex[u]->order < order) {
order = p->nex[u]->order;
ok = p->nex[u]->ok;
}
}
p = p->nex[u];
}
//printf("%d\n", order);
if(is_zero && order == inf) return tag;
return ok;
}
string get_binary(int x) {
stack<int>sta;
do{
sta.push(x%2);
x /= 2;
}while(x);
string ans = "";
//补前缀0
for(int i = 0; i < 8 - sta.size(); ++i) {
ans += '0';
}
//得到二进制
while(!sta.empty()) {
ans += sta.top() + '0';
sta.pop();
}
return ans;
}
void deal(char *s, int ok, int order) {
int len = strlen(s);
int ind = -1;
for(int i = 0; i < len; ++i) {
if(s[i] == '/') {
ind = i;
break;
}
}
string ip = "";
if(ind == -1) ind = len;
for(int i = 0; i < ind;) {
if(s[i] >= '0' && s[i] <= '9') {
int num = 0;
while(i < ind && s[i] >= '0' && s[i] <= '9'){
num = num * 10 + (s[i] - '0');
++i;
}
ip += get_binary(num);
}
else ++i;
}
int n = 32;
if(ind != -1 && ind != len) {
int num = 0;
for(int i = ind+1; i < len; ++i) {
num = num * 10 + s[i] -'0';
}
if(num == 0 && !is_zero) {
is_zero = 1;
tag = ok;
}
n = num;
}
insert(ip, n, ok, order);
}
int main() {
init();
char kind[10], ip[40];
int n, m;
while(scanf("%d%d", &n, &m) == 2) {
is_zero = 0;
for(int i = 0; i < n; ++i) {
scanf("%s %s", kind, ip);
int ok = 0;
if(kind[0] == 'a') ok = 1;
deal(ip, ok, i);
}
for(int i = 0; i < m; ++i) {
scanf("%s", ip);
int x1, x2, x3, x4;
sscanf(ip, "%d.%d.%d.%d", &x1, &x2, &x3, &x4);
string res = get_binary(x1) + get_binary(x2) + get_binary(x3) + get_binary(x4);
if(search(res)) printf("YES\n");
else printf("NO\n");
}
}
return 0;
}
如有不当之处欢迎指出!
hihoCoder 403 Forbidden 字典树的更多相关文章
- ACM学习历程—Hihocoder 1289 403 Forbidden(字典树 || (离线 && 排序 && 染色))
http://hihocoder.com/problemset/problem/1289 这题是这次微软笔试的第二题,过的人比第三题少一点,这题一眼看过去就是字符串匹配问题,应该可以使用字典树解决.不 ...
- [Hihocoder 1289] 403 Forbidden (微软2016校园招聘4月在线笔试)
传送门 #1289 : 403 Forbidden 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 Little Hi runs a web server. Someti ...
- hihoCoder 1014trie树(字典树)
hihoCoder 1014 题目提示已经很清楚了~ 贴代码…… #include <iostream> #include <cstdio> #include <cstr ...
- 微软2016校园招聘4月在线笔试 hihocoder 1289 403 Forbidden
时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描写叙述 Little Hi runs a web server. Sometimes he has to deny acces ...
- 逆序单词 HIhoCoder 1366 字典树
逆序单词 HIhoCoder 1366 字典序 题意 在英文中有很多逆序的单词,比如dog和god,evil和live等等. 现在给出一份包含N个单词的单词表,其中每个单词只出现一次,请你找出其中有多 ...
- hihocoder #1289 : 403 Forbidden (2016 微软编程笔试第二题)
#1289 : 403 Forbidden 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 Little Hi runs a web server. Sometimes ...
- Trie树(字典树)
传送门:http://hihocoder.com/problemset/problem/1014 #1014 : Trie树 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描 ...
- HihoCoder1656 : 前缀后缀查询([Offer收割]编程练习赛39)(字典树+小技巧)
描述 给定一个包含N个单词的字典:{W1, W2, W3, ... WN},其中第i个单词Wi有具有一个权值Vi. 现在小Hi要进行M次查询,每次查询包含一个前缀字符串Pi和一个后缀字符串Si.他希望 ...
- 萌新笔记——用KMP算法与Trie字典树实现屏蔽敏感词(UTF-8编码)
前几天写好了字典,又刚好重温了KMP算法,恰逢遇到朋友吐槽最近被和谐的词越来越多了,于是突发奇想,想要自己实现一下敏感词屏蔽. 基本敏感词的屏蔽说起来很简单,只要把字符串中的敏感词替换成"* ...
随机推荐
- js_1_变量类型
js中有哪些变量类型? 数字(包括int和float),字符串,数组(字典,js没有字典类型,把字典看成一个对象) 如何把字符转成数字呢? obj.parseInt() // 转化成 ...
- JS正则表达式的基础用法
RegExp(正则表达式)对象 正则表达式是一个描述字符模式的对象,可以处理更复杂的字符串.进行匹配替换. 常用的修饰符: i/m/g 使用方法: [声明方法一: new RegExp(value)] ...
- 模态框zeroModal快速引入
最基本快速接入 <%@ page language="java" contentType="text/html; charset=UTF-8" pageE ...
- ssm打印sql语句
在mybatis配置文件中添加<setting name="logImpl" value="STDOUT_LOGGING"/> <?xml v ...
- LINUX读写文件区别
body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...
- wer
概述 快速入门流程: 使用叮当扫码产品请遵循以下操作步骤: 1. 新建项目信息 2. 新建产品信息 3. 添加发货产品 4. 发货 5. 收货 (具体使用操作请查看详细的使用说明) 文档目的: 本文档 ...
- 仿百度糯米TP5项目笔记
需求分析 系统三大模块 商家平台.主平台.前台模块 Thinkphp5.0实战 仿百度糯米开发多商家电商平台网盘下载 (2017-04-24 01:46:23) 转载▼ 第1章 课程简介 本章 ...
- ftp服务配置
文件传输协议(File Transfer Protocol,FTP),基于该协议FTP客户端与服务端可以实现共享文件.上传文件.下载文件. FTP 基于TCP协议生成一个虚拟的连接,主要用于控制F ...
- iOS项目——自定义UITabBar与布局
在上一篇文章iOS项目——基本框架搭建中,我们详细说明了如何对TabBarItem的图片属性以及文字属性进行一些自定义配置.但是,很多时候,我们需要修改TabBarItem的图片和文字属性之外,还需要 ...
- javascript中的BOM对象
1.window对象 所有的浏览器都支持window对象 概念上讲,一个html文档对应一个window对象 功能上讲,控制浏览器窗口 使用上讲,window对象不需要创建对象,直接使用 2.wind ...