微软2017实习生在线笔试题——hihocoder 1289——403 Forbidden
2016-04-10 16:10
399 查看
题目:http://hihocoder.com/problemset/problem/1289
分析:有N条已知的前缀字符串,回答M个query,每个query找到这N个字符串中第一个匹配的项,自然的想到O(length)复杂度的字典树Trie。
由于
(1)1 <= N, M <= 10^5
(2)字符串仅由01组成 >>> Trie的每个node仅含有2个子节点
(3)每个字符串最多包含32个字符 >>> 一个字符串最多需要32个节点来表示
所以,不超过32N(< 3.2*10^6)个节点就可以表示这N条字符串,并且查询不超过32M(< 3.2*10^6)个节点就能完成全部M个query
需要注意的是,和普通的“字符串是否在Trie上”查询不同,题目中的查询要求找到第一个匹配的前缀,所以我们必须在经过每个节点时“看看这个节点的序号是不是更小”
下面是AC代码,对“最多32位的、仅包含01的”字符串,这里用了一个int变量进行表示
分析:有N条已知的前缀字符串,回答M个query,每个query找到这N个字符串中第一个匹配的项,自然的想到O(length)复杂度的字典树Trie。
由于
(1)1 <= N, M <= 10^5
(2)字符串仅由01组成 >>> Trie的每个node仅含有2个子节点
(3)每个字符串最多包含32个字符 >>> 一个字符串最多需要32个节点来表示
所以,不超过32N(< 3.2*10^6)个节点就可以表示这N条字符串,并且查询不超过32M(< 3.2*10^6)个节点就能完成全部M个query
需要注意的是,和普通的“字符串是否在Trie上”查询不同,题目中的查询要求找到第一个匹配的前缀,所以我们必须在经过每个节点时“看看这个节点的序号是不是更小”
下面是AC代码,对“最多32位的、仅包含01的”字符串,这里用了一个int变量进行表示
#include <bits/stdc++.h> using namespace std; const int MAX_N = 100005 * 32; const int kUndefine = 0; const int kDeny = 1; const int kAllow = 2; struct Node { Node* ch[2]; int state; // whether to allow the ip(formed by edges from root to this node) int order; // the rule's index }; Node nodes[MAX_N] = {0}; // initialize all node states to kUndefine int idx = 0; // index of the next available node void insert(Node* p, int ip, int len, int state, int order) { unsigned b = 1 << 31; // as we want an unsigned right shift for(; len--; b >>= 1){ int i = b & ip ? 1 : 0; if(p->ch[i] == 0){ // new a child node p->ch[i] = nodes + idx++; } p = p->ch[i]; } // we can not override former rules with latter ones if(p->state == kUndefine || p->order > order){ p->state = state; p->order = order; } } int check(Node* p, int ip) { int state = kUndefine, order; unsigned b = 1 << 31; for(; b; b >>= 1){ int i = b & ip ? 1 : 0; if(p->ch[i] == 0) break; // stop matching here p = p->ch[i]; if(p->state != kUndefine){ // so p is an ending node here if(state == kUndefine || order > p->order){ state = p->state; order = p->order; } } } return state; } int main() { int i, n, m, a, b, c, d, ip, len, state, global = kUndefine; char s[8]; scanf("%d%d", &n, &m); // build trie Node* root = nodes + idx++; for(i = 0; i < n && global == kUndefine; ++i){ // input: rule ip[/len] scanf("%s %d.%d.%d.%d", s, &a, &b, &c, &d); ip = (a << 24) | (b << 16) | (c << 8) | d; if(getchar() == '/') scanf("%d", &len); else len = 32; // insert trie state = s[0] == 'a' ? kAllow : kDeny; if(len == 0){ // the very last rule that counts (matching everything) global = state; } else insert(root, ip, len, state, i); } // eat all rules after the matching-everything rule for(; i < n; ++i){ scanf("%s %d.%d.%d.%d", s, &a, &b, &c, &d); if(getchar() == '/') scanf("%d", &len); } // do query for(i = 0; i < m; ++i){ scanf("%d.%d.%d.%d", &a, &b, &c, &d); ip = (a << 24) | (b << 16) | (c << 8) | d; state = check(root, ip); if(state == kUndefine){ // no matched prefix, use global rule state = global; } puts(state == kDeny ? "NO" : "YES"); } return 0; }
相关文章推荐
- 在win2012r2上安装KMS模拟器和IDEA激活模拟器并设置开机自启
- poj 3624(01背包)
- shell脚本学习笔记(语法)
- 在Linux下的进程间通信之匿名管道
- UVa 10305 Ordering Tasks 拓扑排序 解题报告
- 团队项目简介及视频
- 读书笔记——《沉思录》(1/4)
- 使用SWIG自动生成JNI代码
- 随机取10个数6
- codeforces 660D (STL map)
- union是什么【编写一个判断大端小段c程序】
- 自定义弹窗
- Java 中的 static 使用之静态方法
- 20145230《java程序设计》第6周学习总结
- 利用kettle对postgresql进行批量加载
- 关于php执行shell脚本
- 第五届华中区程序设计邀请赛 网络赛 Calculation A 【前缀和】
- 蓝桥杯—— 算法训练 图形显示
- Build2016上值得一看的大数据相关Session
- 20145221 《Java程序设计》实验报告一:Java开发环境的熟悉(Windows+IDEA)