51nod 1095 Anigram单词

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1095

竟然错了10次,最后还是用字典树搞过去的,不过这题解法很多,二分,哈希,STL,排序 都可以搞。

字典树建树的时候保存节点出现的次数,因为可能大小写都有,所以开next[52]的数组足够了.

题目关键是相同字符串不能算,那么可以用map统计出现次数最后减去这个即可.

还有就是查找的时候,边查找边记数一直到字符串的结尾,并且如果还有分支的话那么需要减去分支的数,因为是不属于当前字符串的.

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <string>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>
//#pragma comment(linker, "/STACK:102400000,102400000")
#define CL(arr, val)    memset(arr, val, sizeof(arr))

#define ll long long
#define inf 0x7f7f7f7f
#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0)

#define L(x)    (x) << 1
#define R(x)    (x) << 1 | 1
#define MID(l, r)   (l + r) >> 1
#define Min(x, y)   (x) < (y) ? (x) : (y)
#define Max(x, y)   (x) < (y) ? (y) : (x)
#define E(x)        (1 << (x))
#define iabs(x)     (x) < 0 ? -(x) : (x)
#define OUT(x)  printf("%I64d\n", x)
#define lowbit(x)   (x)&(-x)
#define Read()  freopen("a.txt", "r", stdin)
#define Write() freopen("b.txt", "w", stdout);
#define maxn 1010
#define maxv 1010
#define mod 1000000000
using namespace std;

typedef struct node
{
    int count;
    struct node *next[52];
}*tree;

void insert(tree h,string s)
{
    tree p=h;
    int len=s.length();
    for(int i=0;i<len;i++)
    {
        int index=s[i]-‘A‘;
        if(p->next[index]!=NULL)
        {
            p=p->next[index];
            p->count++;
        }
        else
        {
            tree tem=(tree)calloc(1,sizeof(node));
            tem->count=1;
            p->next[index]=tem;
            p=tem;
        }
    }
}

int find(tree h,string s)
{
    tree p=h;
    int len=s.length();
    for(int i=0;i<len;i++)
    {
        int index=s[i]-‘A‘;
        if(p->next[index]==NULL)
            return -1;
        p=p->next[index];
    }
    int ans=p->count;
    for(int i=0;i<52;i++)
        if(p->next[i]!=NULL) ans-=p->next[i]->count;
    //cout<<ans<<endl;
    return ans;
}
int main()
{
    //freopen("a.txt","r",stdin);
    int n,m;
    string s;
    map<string,int>ma;
    cin>>n;
    tree head=(tree)calloc(1,sizeof(node));
    while(n--)
    {
        cin>>s;
        ma[s]++;
        sort(s.begin(),s.end());
        insert(head,s);
    }
    cin>>m;
    while(m--)
    {
        cin>>s;
        int ans=0-ma[s];
        //cout<<ans<<endl;
        sort(s.begin(),s.end());
        int x=find(head,s);
        if(x==-1) cout<<0<<endl;
        else cout<<ans+x<<endl;
    }
    return 0;
}

大神的哈希表代码:

 1 //#pragma comment(linker,"/STACK:102400000,102400000")
 2 #include<stdio.h>
 3 #include<iostream>
 4 #include<string.h>
 5 #include<math.h>
 6 #include<algorithm>
 7 #include<vector>
 8 #include<map>
 9 #include<set>
10 #include<queue>
11 #include<string>
12 #define ll long long
13 #define db double
14 #define PB push_back
15 #define lson k<<1
16 #define rson k<<1|1
17 using namespace std;
18
19 const int N = 10005;
20 const int MOD = 100007;
21 const int base = 57;
22
23 map<string,int> mp;
24 char str[20];
25 int cnt[base+10],h[MOD+10];
26
27 int hs()
28 {
29     memset(cnt,0,sizeof(cnt));
30     for(int i=0;str[i];i++)
31     {
32         if(str[i]>=‘a‘&&str[i]<=‘z‘) cnt[str[i]-‘a‘]++;
33         else cnt[str[i]-‘A‘+26]++;
34     }
35     int res=0;
36     for(int i=0;i<base;i++)
37     {
38         res=(res*base+cnt[i])%MOD;
39     }
40     return res;
41 }
42
43 int main()
44 {
45 #ifdef PKWV
46     freopen("in.in","r",stdin);
47 #endif // PKWV
48     int n;
49     scanf("%d",&n);
50     int lm=1;
51     string s;
52     for(int i=0;i<n;i++)
53     {
54         scanf("%s",str);
55         h[hs()]++;
56         string s=str;
57         if(mp[s]==0) mp[s]=lm++;
58     }
59     int q;
60     scanf("%d",&q);
61     while(q--)
62     {
63         scanf("%s",str);
64         int len=strlen(str);
65         int cnt=0;
66         int res=hs();
67         cnt=h[res];
68         s=str;
69         if(mp[s]>0) cnt--;
70         printf("%d\n",cnt);
71     }
72     return 0;
73 }
时间: 2024-10-14 17:48:42

51nod 1095 Anigram单词的相关文章

51nod 1095 Anigram单词【hash/map/排序/字典树】

1095 Anigram单词 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题  收藏  关注 一个单词a如果通过交换单词中字母的顺序可以得到另外的单词b,那么定义b是a的Anigram,例如单词army和mary互为Anigram.现在给定一个字典,输入Q个单词,从给出的字典中找出这些单词的Anigram. Input 第1行:1个数N,表示字典中单词的数量.(1 <= N <= 10000) 第2 - N + 1行,字典中的单词,单词长度 <= 10

51Nod 1095 Anigram单词 | Hash

Input示例 5 add dad bad cad did 3 add cac dda Output示例 1 0 2 #include <iostream> #include <string.h> #include <algorithm> #include <map> using namespace std; #define MAXN 10001 char s[2*MAXN][15]; char str[15]; map<string,int>

1095 Anigram单词(51nod)

原题链接:http://www.51nod.com/onlineJudge/questionCode.html#problemId=1095&noticeId=20791 老实说这题,我是很不想用字典树,因为不熟~~~但后来没搞出来,就用了字典树..........当然得参考一下大神的代码. 解法:用map统计相同单词... 然后把字符串按字典序排序,然后把字符串插入到字典树里面去 #include<stdio.h> #include<string.h> #include&

[51NOD1095] Anigram单词(map)

题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1095 字典的单词在map中排序和不排序各存1次,查的时候相减. 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 10100; 5 int n, q; 6 char tmp[12]; 7 map<string, int> d1; 8 map<stri

51Nod1095 Anigram单词

题目 一个单词a如果通过交换单词中字母的顺序可以得到另外的单词b,那么定义b是a的Anigram,例如单词army和mary互为Anigram.另:相同的2个单词不算Anigram.现在给定一个字典,输入Q个单词,从给出的字典中找出这些单词的Anigram. 思路 一个map保存原串出现次数,一个map保存排序串出现次数,减一下 代码 #include<bits/stdc++.h> #define ll long long #define db double using namespace s

常见计算机英语单词

1. file n. 文件:v. 保存文件 2. command n. 命令指令 3. use v. 使用用途 4. program n. 程序 5. line n. (数据程序)行线路 6. if conj. 如果 7. display vt. 显示显示器 8. set v. 设置n. 集合 9. key n. 键关键字关键码 10. list n. 列表显示v. 打印 11. by prep. 凭靠沿 12. press v. 按压 13. with prep. 用与随着 14. forma

004、单词吗?

15:43 2015-04-07 什么是英语单词?只是要连着写,中间没有空白符(空格.换行.Tab.等)的,都是英语单词,是吗?是的,英国佬估计就是这样想的.在29本著作,18个作者,四百六十万个单词中,统计出最常用的一千个单词中,居然包括这些: don'tI'llit'scan'tI'mwon'tthere'sI'vedidn'the'sfather'syou'llman's'emo'clockwouldn'tshe'smother'sma'amcouldn't I 服了 U !早就想整理这一

51nod 1201 整数划分(dp)

题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1201 题解:显然是一道dp,不妨设dp[i][j]表示数字i分成j个一共有几种分法. 那么转移方程式为: dp[i][j] = dp[i - 1][j] + dp[i - 1][j - 1] 表示将i - 1划分为j个数,然后j个数都+1 还是不重复,将i - 1划分为j - 1个数,然后j - 1个数都+1,再加上1这个数. 然后就是j的范围要知道1+2+

html常用单词

htmllss常用单词head头body身体title标题table表格list列表item条款row行column列form表单input输入text文本password密码submit提交reset重置button按钮image图像anchor锚audio音频的video视频ruler标尺division划分label标签style样式script脚本select选择option选项paragraph段落color颜色backgyound背景class类blink闪烁italic斜体soli