UVa 10887 - Concatenation of Languages

本文探讨使用哈希表技术解决语言组合计数问题,通过实例解析如何高效地计算两个单词集合并后的字符串数量,涉及字符串操作、哈希表应用及输入输出细节。

链接:

UVa :  http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=1828


类型:  哈希表


原题:

A language is a set of strings. And the concatenation of two languages is the set of all strings that are formed by concatenating the strings of the second language at the end of the strings of the first language.

 

For example, if we have two language A and B such that:

A = {cat, dog, mouse}

B = {rat, bat}

The concatenation of A and B would be:

C = {catrat, catbat, dograt, dogbat, mouserat, mousebat}

 

Given two languages your task is only to count the number of strings in the concatenation of the two languages.

 

样例输入;

2

3 2

cat

dog

mouse

rat

bat

1 1

abc

cab

样例输出:

Case 1: 6

Case 2: 1

 

题目大意:

有单词集合A和集合B, 然后有这两个集合可以组成新的复合词,其中A中的是复合词的前半部分,B中的是后半部分。给出A,B两集合,问最多能组合出多少个符合单词?


分析与总结:

这题感觉就是UVa 10391 - Compound Words 的兄弟篇, 挺像的。

还是用哈希来判重。没组出一个新单词就尝试加入哈希表中, 如果成功加入,那么就加1。


这题因为滥用memcmp和memspy来处理字符串而WA了多次。


还有一个很坑爹的,读入单词要用gets, 因为有可能是有空行的单词....



/*
 * Uva 10887 - Concatenation of Languages 
 * 哈希表
 * Time: 0.404s (UVa)
 * Author: D_Double
 */
#include<iostream>
#include<cstring>
#include<cstdio>
#define MAXN 1503
using namespace std;

char A[MAXN][12], C[MAXN*MAXN][24];
const int HashSize = MAXN*MAXN;
int head[HashSize], next[HashSize], rear, ans;

inline void init(){ rear=1; ans=0;  memset(head, 0, sizeof(head)); }

inline int hash(char *str){
    int seed=131, v=0;
    while(*str) v = v*seed + (*str++);
    return (v & 0x7FFFFFFF)%HashSize;
}

int try_to_insert(int s){
    int h = hash(C[s]);
    int u = head[h];
    while(u){
        if(strcmp(C[u], C[s])==0) return 0;
        u = next[u];
    }
    next[s] = head[h];
    head[h] = s;
    return 1;
}

int main(){
    int T, M, N, cas=1;
    scanf("%d%*c", &T);
    while(T--){
        scanf("%d %d%*c",&M,&N);
        for(int i=0; i<M; ++i) gets(A[i]);

        init();

        char str[12], link_word[24];
        for(int j=0; j<N; ++j){
            gets(str);
            for(int i=0; i<M; ++i){
                strcpy(link_word, A[i]);
                strcat(link_word, str);
                strcpy(C[rear], link_word);
                if(try_to_insert(rear)){ ++rear; ++ans; }
            }
        }
        printf("Case %d: %d\n", cas++, ans);
    }
    return 0;
}

——  生命的意义,在于赋予它意义。

          
     原创 http://blog.youkuaiyun.com/shuangde800 , By   D_Double  (转载请标明)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值