[HihoCoder]#1289 : 403 Forbidden

来源:互联网 发布:手机淘宝如何上架宝贝 编辑:程序博客网 时间:2024/06/14 10:26

华电北风吹
天津大学认知计算与应用重点实验室
2016-07-27

题目链接:
http://hihocoder.com/problemset/problem/1289

题目分析:
笔试的时候用python做的,暴力求解。对每一个查询,按照先后顺序把规则匹配一遍,得了40分。下来后用C++版本的trie树写了一个超时,修改为C语言版accept.用时好久,不过ac还是很高兴。

参考代码:

#define MAXN 1000005#include <string.h>#include <stdio.h>using namespace std;int RuleEmptyFlag;struct TrieNode{    bool access, existed;    int ruleID;    TrieNode* next[2];    TrieNode()    {        access = false;        existed = false;        ruleID = MAXN;        memset(next, NULL, sizeof(next));    }};void Insert(TrieNode* root, long long word, int maskNum, bool access, int ruleID){    TrieNode* node = root;    long long bit = 1;    bit = bit << (maskNum - 1);    for (int i = 0; i < maskNum; i++)    {        int id = (bit&word)>0 ? 1 : 0;        if (node->next[id] == NULL)        {            node->next[id] = new TrieNode();        }        node = node->next[id];        bit = bit >> 1;    }    if (node->existed == false)    {        node->existed = true;        node->access = access;        node->ruleID = ruleID;    }}bool Search(TrieNode* root, long long word){    TrieNode* node = root;    long long bit = 1;    bit = bit << 31;    int ruleID = MAXN;    bool result = root->access;    for (int i = 0; i < 32; i++)    {        int id = (bit&word)>0 ? 1 : 0;        node = node->next[id];        if (node == NULL)        {            break;        }        if (node->existed)        {            if (node->ruleID < ruleID)            {                ruleID = node->ruleID;                result = node->access;            }        }        bit = bit >> 1;    }    if (ruleID == MAXN)    {        if (RuleEmptyFlag != 0)        {            return true;        }        else        {            return false;        }    }    else    {        return result;    }}long long ConnectBinIPNum(int ip1, int ip2, int ip3, int ip4, int maskNum){    long long result = 0;    result = result | ip1;    result = result << 8;    result = result | ip2;    result = result << 8;    result = result | ip3;    result = result << 8;    result = result | ip4;    result = result >> (32 - maskNum);    return result;}int main(){    TrieNode* root = new TrieNode();    int N, M;    scanf("%d %d", &N, &M);    char access[10], ipRule[20];    RuleEmptyFlag = -1;    int ip1, ip2, ip3, ip4;    for (int i = 0; i < N; i++)    {        scanf("%s %s", access, ipRule);        bool maskFlag = false;        int ipRuleLength = strlen(ipRule);        for (int j = ipRuleLength - 1; j >= 0; j--)        {            if (ipRule[j] == '/')            {                maskFlag = true;                break;            }        }        int maskNum = 32;        if (maskFlag)        {            sscanf(ipRule, "%d.%d.%d.%d/%d", &ip1, &ip2, &ip3, &ip4, &maskNum);        }        else        {            sscanf(ipRule, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);        }        long long item = ConnectBinIPNum(ip1, ip2, ip3, ip4, maskNum);        if (maskNum == 0)        {            if (RuleEmptyFlag == -1)            {                if (access == "allow")                {                    RuleEmptyFlag = 1;                }                else                {                    RuleEmptyFlag = 0;                }            }        }        if (strcmp(access, "allow") == 0)        {            Insert(root, item, maskNum, true, i);        }        else        {            Insert(root, item, maskNum, false, i);        }    }    while (M--)    {        scanf("%s", ipRule);        sscanf(ipRule, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);        long long item = ConnectBinIPNum(ip1, ip2, ip3, ip4, 32);        if (Search(root, item))            printf("YES\n");        else            printf("NO\n");    }    return 0;}

C++版本的如下,虽然超时错误,但是里面用到的函数还是很有参考价值。

#define MAXN 1000005#include <iostream>#include <string>#include <string.h>#include <sstream>#include <vector>using namespace std;int RuleEmptyFlag;void split(string &s, string &delim, vector<string> &ret){    size_t last = 0;    size_t index = s.find_first_of(delim, last);    while (index != string::npos)    {        ret.push_back(s.substr(last, index - last));        last = index + 1;        index = s.find_first_of(delim, last);    }    if (index - last>0)    {        ret.push_back(s.substr(last, index - last));    }}struct TrieNode{    bool access, existed;    int ruleID;    TrieNode* next[2];    TrieNode()    {        access = false;        existed = false;        ruleID = MAXN;        memset(next, NULL, sizeof(next));    }};void Insert(TrieNode* root, string word, bool access, int ruleID){    TrieNode* node = root;    for (int i = 0; i < word.length(); i++)    {        int id = word[i] - '0';        if (node->next[id] == NULL)        {            node->next[id] = new TrieNode();        }        node = node->next[id];    }    if (node->existed == false)    {        node->existed = true;        node->access = access;        node->ruleID = ruleID;    }}bool Search(TrieNode* root, string word){    TrieNode* node = root;    int ruleID = MAXN;    bool result = root->access;    for (int i = 0; i < word.length(); i++)    {        int id = word[i] - '0';        node = node->next[id];        if (node == NULL)        {            break;        }        if (node->existed)        {            if (node->ruleID < ruleID)            {                ruleID = node->ruleID;                result = node->access;            }        }    }    if (ruleID == MAXN)    {        if (RuleEmptyFlag!=0)        {            return true;        }        else        {            return false;        }    }    else    {        return result;    }}string NumToBitString(int num){    string result = "";    while (num > 0)    {        if (num & 1)        {            result = "1" + result;        }        else        {            result = "0" + result;        }        num = num >> 1;    }    while (result.size() < 8)    {        result = "0" + result;    }    return result;}int StringToNum(string str){    int result;    stringstream s;    s << str;    s >> result;    return result;}string GetRule(string ipRule){    string result = "";    vector<string> ipCount;    string delim = "/";    split(ipRule, delim, ipCount);    string ip = ipCount[0];    vector<string> delim_ip;    delim = ".";    split(ip, delim, delim_ip);    for (int i = 0; i < delim_ip.size(); i++)    {        result += NumToBitString(StringToNum(delim_ip[i]));    }    if (ipCount.size()>1)    {        int length = StringToNum(ipCount[1]);        return result.substr(0, length);    }    else    {        return result;    }}int main(){    TrieNode* root = new TrieNode();    int N, M;    string access,ipRule;    RuleEmptyFlag = -1;    cin >> N >> M;    for (int i = 0; i < N; i++)    {        cin >> access;        cin >> ipRule;        string item = GetRule(ipRule);        if (item.length() == 0)        {            if (RuleEmptyFlag == -1)            {                if (access == "allow")                {                    RuleEmptyFlag = 1;                }                else                {                    RuleEmptyFlag = 0;                }            }        }        if (access == "allow")        {            Insert(root, item, true, i);        }        else        {            Insert(root, item, false, i);        }    }    while (M--)    {        string queryIP, queryString;        cin >> queryIP;        queryString = GetRule(queryIP);        if (Search(root, queryString))            cout << "YES" << endl;        else            cout << "NO" << endl;    }    return 0;}
0 0
原创粉丝点击