UVALive 7712 Confusing Manuscript 字典树 查询与s的编辑距离为1的字符串数量

/**
题目:UVALive 7712 Confusing Manuscript
链接:https://vjudge.net/problem/UVALive-7712
题意:给定n个不同的字符串,f(i)表示第i个字符串和其他字符串的编辑距离为1的个数。
编辑距离为1表示两个字符串其中一个可以通过删除任意位置某一个字符或者增加任意位置某一个字符或者替换任意位置某一个字符之后,两者匹配。
输出f(i)最大的字符串,如果f(i)==f(j) (i<j) 输出第i个字符串。
思路:字典树
主要是处理细节。首先插入所有字符串。
然后枚举处理每个字符串s,对当前s,先从字典树删除它,然后query,最后插回字典树。

主要是query细节,以下都是对当前s进行处理:
int query(int u,char *s,int pos,int mofa) ; mofa表示当前是否进行以下三种操作任意一种。

1,add
可以直接和当前字典树的某个匹配,自身pos不加。
特殊情况:如果s[pos]==‘\0‘;那么直接找字典树当前位置上存在的叶子节点。
2,cut
字典树当前位置不变,s的pos+1;
特殊情况:s[pos+1]==‘\0‘;那么删除当前就没有了,所以计算结果为pos-1那一层的叶子节点。
实际上就是当前的u,判断val[u]就可以知道是否是叶子节点。
3,replace
直接替换。

*/

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
using namespace std;
typedef pair<int,int> P;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int maxnode = 50000*10+10;///最多可能有多少个节点
const int maxn = 5e4+10;
const int sigma_size = 26;///0或者1
int ch[maxnode][sigma_size];///由于很大,所以结构体内部放不下。要放在外面。
char s[maxn][11];
int ans = 0;
int anspos;
struct Trie{
    int val[maxnode];
    int sz;
    int idx(char c){return c-‘a‘;}

    void insert(char *s)
    {
        int u = 0, c;
        for(int i = 0; s[i]!=‘\0‘; i++){
            c = idx(s[i]);
            if(!ch[u][c]){
                memset(ch[sz], 0, sizeof ch[sz]);
                ch[u][c] = sz;
                val[sz++] = 0;
            }
            u = ch[u][c];
        }
        val[u]=1;///表示该节点存在该单词。
    }
    void del(char *s)
    {
        int u = 0, c;
        for(int i = 0; s[i]!=‘\0‘; i++){
            c = idx(s[i]);
            u = ch[u][c];
        }
        val[u]=0;
    }

    int query(int u,char *s,int pos,int mofa)
    {
        int c = idx(s[pos]);;
        int cnt = 0;
        if(mofa==0){
            if(ch[u][c]==0) return 0;
            if(s[pos+1]==‘\0‘){
                return val[ch[u][c]];
            }else
            {
                return query(ch[u][c],s,pos+1,0);
            }
        }else
        {
            ///add
            if(s[pos]==‘\0‘){
                for(int i = 0; i < 26; i++){
                    if(ch[u][i]) cnt += val[ch[u][i]];
                }
                return cnt;///不可以再进行删除和替换操作了。
            }else{
                for(int i = 0; i < 26; i++){
                    if(ch[u][i]==0) continue;
                    cnt += query(ch[u][i],s,pos,0);
                }
            }

            ///cut
            if(s[pos+1]==‘\0‘){
                cnt += val[u];
            }else
                cnt += query(u,s,pos+1,0);

            ///replace

            for(int i = 0; i < 26; i++){
                if(ch[u][i]==0) continue;
                if(i!=c){
                    if(s[pos+1]==‘\0‘){
                        cnt += val[ch[u][i]];
                    }else
                        cnt += query(ch[u][i],s,pos+1,0);
                }
            }

            ///bu bian
            if(ch[u][c]){
                cnt += query(ch[u][c],s,pos+1,1);
            }

            return cnt;
        }
    }
};
int main()
{
    int T, n;
    Trie trie;
    int cas = 1;
    cin>>T;
    while(T--)
    {
        scanf("%d",&n);
        trie.sz = 1;
        memset(ch[0], 0, sizeof ch[0]);
        for(int i = 0; i < n; i++){
            scanf("%s",s[i]);
            trie.insert(s[i]);
        }
        ans = 0, anspos = 0;//!
        for(int i = 0; i < n; i++){
            trie.del(s[i]);
            int temp = trie.query(0,s[i],0,1);
            //cout<<s[i]<<endl;
            //cout<<temp<<endl;
            if(temp>ans){
                ans = temp; anspos = i;
            }
            trie.insert(s[i]);
        }
        printf("Case #%d: %s\n",cas++,s[anspos]);
    }
    return 0;
}
时间: 2024-10-09 18:27:59

UVALive 7712 Confusing Manuscript 字典树 查询与s的编辑距离为1的字符串数量的相关文章

CodeForces 706D Vasiliy&#39;s Multiset (字典树查询+贪心)

题意:最开始的时候有一个集合,集合里面只有一个元素0,现在有q次操作,操作分为3种: + x: 表示向集合中添加一个元素x - x:表示删除集合中值为x的一个元素 ? x:表示查询集合中与x异或的最大值为多少 析:这是一个字典树的应用,不过确实没看出来....主要思想是这样,先用10进制数,转成二进制数,记下每个结点的0,1的个数,这样增加和删除,就是对01的删除, 剩下的就是查询,那么尽量让0和1XOR是最大的,所以,对于给定数,我们要去尽量他的XOR数,如果找到就加上,找不到,就找下一个.这

基础字典树查询前缀

题目1 : Trie树 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进. 这一天,他们遇到了一本词典,于是小Hi就向小Ho提出了那个经典的问题:“小Ho,你能不能对于每一个我给出的字符串,都在这个词典里面找到以这个字符串开头的所有单词呢?” 身经百战的小Ho答道:“怎么会不能呢!你每给我一个字符串,我就依次遍历词典里的所有单词,检查你给我的字符串

利用01字典树查询最大异或值

01字典树的是只含有0和1两种字符的字典树,在使用它的时候,把若干数字转成二进制后插入其中 在查询树中的哪个数字和给定数字有最大异或值的时候,从根开始贪心查询就ok了 HDU4825是一道裸题:给出n个数和m次询问,每次询问给出一个数x,问在n个数中哪个数与x异或值最大 1 #include<cstdio> 2 #include<cstring> 3 const int maxn=1000005; 4 int n,m,rt; 5 int a[maxn],v[3500005],s[3

UVALive 5029 字典树

E - Encoded Barcodes Crawling in process...Crawling failedTime Limit:3000MS    Memory Limit:0KB    64bit IO Format:%lld & %llu SubmitStatusPracticeUVALive 5029 Description All the big malls need a powerful system for the products retrieval. Now you a

poj 3764 The xor-longest Path(字典树)

题目链接:poj 3764 The xor-longest Path 题目大意:给定一棵树,每条边上有一个权值,找出一条路径,使得路径上权值的亦或和最大. 解题思路:dfs一遍,预处理出每个节点到根节点路径的亦或和rec,那么任意路径均可以表示rec[a] ^ rec[b],所以问题 就转换成在一些数中选出两个数亦或和最大,那么就建立字典树查询即可. #include <cstdio> #include <cstring> #include <algorithm> us

【BZOJ2741】【FOTILE模拟赛】L 可持久化字典树+分块

广告: #include <stdio.h> int main() { puts("转载请注明出处[vmurder]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/44496739"); } 题解: 首先我们处理出来sum[0,n]作为异或前缀和,然后答案就不再是[l,r]中间某段区间的异或和,而转化成求了[l?1,r]中任意两点异或和的最大值. 然后我们分块处理出fi,j表示 [第i块的开头,j

codeforces 455B A Lot of Games(博弈,字典树)

题目大意:给定n,表示字符串集合.给定k,表示进行了k次游戏,然后是n个字符串.每局开始,字符串为空串,然后两人轮流在末尾追加字符,保证新的字符串为集合中某字符串的前缀,不能操作者输,新一轮由上一句输的人先手. 解题思路:首先对字符集合建立字典树,然后根据博弈的必胜必败性质搜索出先手的决策状态,可决定胜败3,只能胜利2,只能失败1,不可掌控(即对手可决定胜败)0. 对于状态3,为必胜,可以采用前K-1场败,然后保证第K场自己先手,取必胜方案. 对于状态2,无论则们走都是赢的话,肯定是两个人轮流胜

hust 1605 - Gene recombination(bfs+字典树)

1605 - Gene recombination Time Limit: 2s Memory Limit: 64MB Submissions: 264 Solved: 46 DESCRIPTION As a gene engineer of a gene engineering project, Enigma encountered a puzzle about gene recombination. It is well known that a gene can be considered

字符串hash与字典树

title: 字符串hash与字典树 date: 2018-08-01 22:05:29 tags: acm 算法 字符串 概述 这篇主要是关于字符串里的 字符串hash 和 字符串字典树,,两个都是简单的套模板的东西,,,理解基本思想就行了,,,对了,,还有一个字典树的的变形--01字典树: 字符串hash 如何求一个字符串的hash值 字符串hash的作用就是将 字符串有效的转化为一个整数 ,,这个转化过程利用的是一个 hash函数 例如,,我们选hash函数为 \(hash[i]=(has