hiho1289-字典树

首先要自我检讨一下,英语不好读错两遍题意啊!!!弄明白了很快就A了啊!!。。。反正我是没长脑子吧。


说一下题意,这个题大概是给你一堆规则,分为A和D,其中有些是一个区间,也就是二进制的前多少位符合就行了。
然后还有一下查询,以查到的第一个匹配为准,没有默认YES,这里唯一的问题就是查以第一个查到的为准,下面分析。


这个题就是分两步,第一步模拟输入转化一下,脑残string搞的很麻烦,其实scanf(“%d.%d.%d.%d”)再加一个getline来读取’/‘或者都加一个’.‘什么的爽一下多好啊!人傻自带复杂度。。。第二步就是对于规则建立一下字典树,要注意建立的“单词”长短不一样,那么建立的时候就在单词末尾赋予一个值就好了,这样查询的时候记录碰到的值就可以了,然后考虑要一个一个匹配,这样可以用一个小技巧,让开始赋值的比较大,每次赋值也取最大的,然后查询也返回最大的就行了。。。


代码写的巨搓,这里主要提供思路。。。



#include <stdio.h>
#include <cmath>
#include <iostream>
#include <string>
#include <algorithm>
#include <sstream>
#include <vector>
using namespace std;
#define  MAX  2
vector<string> v;
typedef struct TrieNode{
	int nCount;
	struct TrieNode *next[MAX];
} TrieNode;

TrieNode Memory[1500000];
int allocp = 0;

TrieNode * createTrieNode(){
	TrieNode * tmp = &Memory[allocp++];
	tmp->nCount = 0;
	for (int i = 0; i < MAX; i++)
		tmp->next[i] = NULL;
	return tmp;
}

void insertTrie(TrieNode * * pRoot,const char * str,int cc,int num){
	TrieNode * tmp = *pRoot;
	int i = 0, k;
	int cnt=0;
    if(cc==0)
        tmp->nCount=max(num,tmp->nCount);
	while (str[i]){
        cnt++;
		k = str[i] - '0';
		if (tmp->next[k]){
		    if(cnt==cc)
                tmp->next[k]->nCount=max(num,tmp->next[k]->nCount);
		}
		else{
			tmp->next[k] = createTrieNode();
            if(cnt==cc)
                tmp->next[k]->nCount=max(num,tmp->next[k]->nCount);
		}
		tmp = tmp->next[k];
		i++;
	}
}

int searchTrie(TrieNode * root,const char * str){
	if (root == NULL)
		return 0;
	TrieNode * tmp = root;
	int i = 0, k;
	int ans=tmp->nCount;
	while (str[i]){
		k = str[i] - '0';
		if (tmp->next[k]){
			tmp = tmp->next[k];
			ans=max(tmp->nCount,ans);
		}
		else
			return ans;
		i++;
	}
	return ans;
}

int po(int x){
    int ret=1;
    if(x!=1)
        ret=10;
    return ret;
}

string tran(string s){
    string ans;
    int last=0;
    s+='.';
    for(int i=0;i<s.size();i++){
        if(s[i]=='.'||s[i]=='/'){
            int in=0;
            stringstream stm;
            stm<<s.substr(last,i-last);
            stm>>in;
            ans+=v[in];
            last=i+1;
        }
        if(s[i]=='/')
            break;
    }
    return ans;
}
int pan(string s){
    string ans;
    int bo=0,cnt=0;
    for(int i=0;i<s.size();i++){
        if(s[i]=='/'){
           bo=1;
           continue;
        }
        if(bo==1)
            cnt+=(s[i]-'0')*(po(s.size()-i));
    }
    if(bo==0){
        return 32;
    }
    else{
        return cnt;
    }
}

void add(string s,TrieNode *Root,int x,int num)
{
    int jia=1;
    const char *ss=s.substr(0,x).c_str();
    insertTrie(&Root, ss,x,num);
}

void init(){
    for(int i=0;i<=256;i++){
        int xx=i;
        string p;
        while(xx){
            int x=xx%2;
            xx/=2;
            p=(char)('0'+x)+p;
        }
        while(p.size()<8){
            p=(char)('0')+p;
        }
        v.push_back(p);
    }
}

int main()
{
    init();
    int n,m;
    cin>>n>>m;
    string s1,s2;
	TrieNode *Root = createTrieNode();
	TrieNode *Root2 = createTrieNode();
	int cnt=100005;
    char ss1[50],ss2[50];
    for(int i=0;i<n;i++){
        scanf("%s%s",&ss1,&ss2);
        s2=string(ss2);
        if(ss1[0]=='a'){
            int xx=pan(s2);
            s2=tran(s2);
            add(s2,Root,xx,cnt);
        }
        else{
            int xx=pan(s2);
            s2=tran(s2);
            add(s2,Root2,xx,cnt);
        }
        cnt--;
    }
    for(int i=0;i<m;i++){
        scanf("%s",&ss1);
        s1=(string)ss1;
        s1=tran(s1);
        int r1=searchTrie(Root2, s1.c_str());
        int r2=searchTrie(Root, s1.c_str());
        if(r1==0&&r2==0){
            cout<<"YES\n";
        }
        else if(r2<r1){
            cout<<"NO\n";
        }
        else{
            cout<<"YES\n";
        }
    }
	return 0;
}

你可能感兴趣的:(hiho1289-字典树)