CODE[VS]1018 单词接龙

题目:http://codevs.cn/problem/1018/
思路:合并字符串a,b。从字符串a的末尾字符a[ai]与字符串b的首字符b[bi]进行匹配,如果不相等,则ai - 1;如果相等,则匹配ai+x,与bi+x的字符是否相等,如果到达字符串a的结尾且ai不等于0,即b不包含a,则表示合并成功,记录合并位置,否则ai - 1。
题解:

/* 1018 单词接龙 */ 
#include <stdio.h>
#include <stdlib.h> 

#define DEBUG

#define MAXN 20     /* 最大单词数 */
#define MAXL 50     /* 最长的单词长度 */

int n;                      /* 单词数 */
char words[MAXN][MAXL];     /* 所有单词 */ 
char st_ch;                 /* 开始单词 */ 
int use[MAXN];              /* 使用表 */ 
int maxl;                   /* 最长接龙数 */ 

/* 获取字符串长度 */
int get_len(char *str){
    int l = 0;
    while('\0' != str[l]){
        l++;
    }
    return l;
} 
/* 连接两个单词,可连接返回连接后的字符串,否则NULL */
char* conn_str(char *stra, char *strb){
    int ai, bi;
    int x;
    char *strc = NULL;
    int done;
    int la, lb, lc;
    /* 计算字符串长度 */ 
    la = get_len(stra);
    lb = get_len(strb);
    /* 遍历字符串a,b, 查询重复字符串 */ 
    ai = bi = 0;
    done = 0;
    for(ai = la - 1; ai >= 0; ai--){
        /* 如果两字符串相等,则继续判断下一个字符 */ 
        if(stra[ai] == strb[bi]){
            /* 判断接下来的字符,直到不等,或者字符串a,b结束 */ 
            for(x = 1; (ai + x) < la && (bi + x) < lb; x++){
                /* 字符串b已结束或者字符串a,b不再相等 */ 
                if(stra[ai + x] != strb[bi + x]){
                    break;
                }
            }
            /* 字符串a结束且字符串b不包含字符串a,匹配成功 */
            if((ai + x) == la && 0 != ai){
                done = 1;
                break;
            }
        }
    }
    /* 匹配成功,合并字符串a和b */ 
    if(1 == done){
        lc = la + lb - x;
        strc = (char*) malloc(lc + 1);
        for(x = 0; x < ai; x++){
            strc[x] = stra[x];
        } 
        for(bi = 0; bi < lb; bi++){
            strc[x + bi] = strb[bi];
        }
        strc[lc] = '\0';
        /* 测试 - 打印合并后的字符串 */            
        // printf("%s + %s = %s [%d]\n", stra, strb, strc, get_len(strc));
    }
    return strc;
}

/* 深度搜索所有合并可能 */
void dfs_conn_strs(char *str){
    int i;
    char *tmp;
    int l;
    /* 遍历所有字符串,查找可能的连接字符串 */ 
    for(i = 0; i < n; i++){
        /* 当前字符串未被使用, 且可以连接 */ 
        if(0 != use[i] && NULL != (tmp = conn_str(str, words[i]))){
            use[i] = use[i] - 1;
            dfs_conn_strs(tmp);
            use[i] = use[i] + 1;
            free(tmp);
        }
    }
    /* 搜索完毕,计算长度 */
    l = get_len(str);

    if(l > maxl){
        maxl = l;
    }
    /* 测试 - 打印合并的字符串 */
    // printf("%s\n", str); 
} 

/* 主函数入口 */ 
int main(int argc, char *argv[]) {
    int i;      /* 索引值 */ 

#ifdef DEBUG
    FILE *fp;
    if(NULL == (fp = fopen("data.txt", "r"))){
        return 1;
    } 
#endif
    /* 获取单词数 */
#ifdef DEBUG
    fscanf(fp, "%d", &n);
#else
    scanf("%d", &n);
#endif
    /* 获取所有单词 */
    for(i = 0; i < n; i++){
#ifdef DEBUG
        fscanf(fp, "%s", words[i]);
#else
        scanf("%s", words[i]);
#endif
    } 
    /* 获取起始单词 */ 
#ifdef DEBUG
        fscanf(fp, "\n%c", &st_ch);
#else
        scanf("\n%c", &st_ch);
#endif

    /* 初始化单词使用表 */
    for(i = 0; i < n; i++){
        use[i] = 2;
    } 
    /* 测试 - 打印所有单词 */
    /*
    for(i = 0; i < n; i++){
        printf("%s\n", words[i]);
    } 
    printf("%c\n", st_ch);
    */ 
    /* 搜索最长接龙 */ 
    maxl = 0;
    for(i = 0; i < n; i++){
        if(st_ch == words[i][0]){
            use[i] = use[i] - 1;
            dfs_conn_strs(words[i]);
            use[i] = use[i] + 1;
        }
    }
    /* 输出结果值 */ 
    printf("%d", maxl);
#ifdef DEBUG
    fclose(fp);
#endif
    return 0;
}

猜你喜欢

转载自blog.csdn.net/QQ604666459/article/details/77895279