UVALive 6133_Cellphone Typing题解

题意:N个单词的字典,求这N个的单词的平均敲击键盘的次数,也就是敲击键盘总数/N个单词。

1、每个单词的第一个字母必须敲击

2、如果一个字母的子节点超过一个或者,该字母为某个单词的结束字母,则下一个字母也要敲击一次。也就是说前一个字母决定下一个字母是否需要敲击

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<cmath>
using namespace std;
struct Trie  //字典树结构
{
    Trie *child[26];
    int num;   //子节点数
    bool end;  //判断该字母是否为某个单词的结束字母
    Trie() //构造函数
    {
        num=0;
        end=0;
        memset(child,0,sizeof(child));
    }
};
Trie *root,*s,*lrelia;
void Create(char *str)  //插入单词
{
    s=root;
    int i=0;
    while(str[i])
    {
        int id=str[i]-'a';
        if(s->child[id]==0) //如果该字母还没有出现在字典中
        {
        s->child[id]=new Trie;
        s->num++; //子节点数+1
        s=s->child[id];
        }
        else
        {
            s=s->child[id];
        }
        i++;
    }
    s->end=1;//标记单词的最后一个字母
}
double Search(char *str)
{
    s=root;
    double len=1; //因为第一个字母必须得敲击,所以len赋值1,
    int o=strlen(str);
    /*
     既然前一个字母的子节点数决定下一个字母是否要敲击,
     我们只需要遍历第1个到len-1个字母就可以了。
    */
    for(int i=0;i<o-1;++i)
    {
        int id=str[i]-'a';
        s=s->child[id];
        if(s->num>1||s->end==1) len++;
    }
    return len;
}

char a[100002][90];
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        root=new Trie; //重新初始化字典树
        for(int i=0;i<n;++i)
        {
            scanf("%s",a[i]);
            Create(a[i]);
        }
        double l=0;//所有单词的敲击总长度
        for(int i=0;i<n;++i)
            l+=Search(a[i]); //每个单词单加的结果。
        printf("%.2lf\n",l/n);//总长度除以n个单词
    }
    return 0;
}

 

 

转载于:https://www.cnblogs.com/A-way/archive/2013/04/23/3038924.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值