hdu1251 字符统计

这道题目没有输入范围提示,比较恶心,但直觉告诉我机械式的顺序扫描肯定超时 同时也不知道会不会卡内存  也不敢贸然用string,还是用char*比较保险 还是比较习惯用二分查找,居然一次AC 效率还挺高  很happy

 

不过遇到一个问题 元素为char[10]使用sort函数报错 说无法转换,郁闷 无奈干脆使用一个结构体 只含这个字符串  汗

大概是因为 字符二维数组和 字符串的一维数组还是有区别的 不是每个一维数组后面都有一个结束符 只是分配一个比较大的整体区域

二维数组只是增加了定位信息 但还是一个整体

 

#include<cstring>
#include<iostream>
#include<iomanip>
#include<algorithm>
using namespace std;

struct word
{
 char name[10];
};
word dictionary[100000];

int cmp(word s1,word s2)
{
 return strcmp(s1.name,s2.name)<0;
}

void bi_search(char* s,int top)
{
 int low,high,mid,len;
 low=0;high=top;
 len=strlen(s);
 while(low<=high)
 {
  mid=(low+high)/2;
  if(strcmp(dictionary[mid].name,s)==0)break;
  else if(strcmp(dictionary[mid].name,s)>0)high=mid-1;
  else low=mid+1;
 }
 if(strcmp(s,dictionary[mid].name)>0)low=mid+1;//定位开始位置
 else low=mid;

 char maxbound[12];
 strcpy(maxbound,s);
 for(int i=len;i<11;i++)maxbound[i]='z';
 maxbound[11]='/0';
 while(strcmp(dictionary[mid].name,maxbound)<=0&&mid<=top)mid++;
 high=mid-1;
 cout<<high-low+1<<endl;
}

int main()
{
 int top=-1;
 char input[15];
 while(gets(input)&&strlen(input)!=0)
  strcpy(dictionary[++top].name,input);

 sort(dictionary,dictionary+top+1,cmp);

 while(cin>>input)
 {
  bi_search(input,top);
 }

   return 0;
}

 

 

时间 140ms  内存1200k   二分定位法确实比较高效(二分查找定位下界,注意构造一个上界的小技巧)

看到网上很多牛牛都是用 所谓的字典树 没有接触过 但大概知道是怎样的结构,随便用了个版本提交一下 内存使用量有点吓人40+M

时间效率好不错 90ms  这道题目还是我的方法好点

 

字典树版本:

  #include<stdio.h>
  #include <stdlib.h>
  #include<string>
  using namespace std;
  struct distree{
      int n;
      struct distree * child[26];
  };
  struct distree *root;
  void Ins(char *ch)
  {
     int i;
     struct distree *p,*newnode;
     p = root;
     for (;*ch;ch++)
     {
         if(p->child[*ch - 'a'])
         {
             p = p->child[*ch - 'a'];
             p->n ++;
         }
         else
         {
             newnode = (struct distree *)new(distree);
             for (i=0;i<26;i++)
                 newnode->child[i] = 0;
             p->child[*ch - 'a'] = newnode;
             p = newnode;
             p->n = 1;
         }
     }
 }
 int find(char *ch)
 {
     struct distree *p;
     p = root;
     for(;*ch;ch++)
     {
         if(p->child[*ch -'a'])
             p = p->child[*ch - 'a'];
         else
             return 0;
     }
     return p->n;
 }
 int main()
 {
     int i;
     char ch[11];
     root = (struct distree *)malloc(sizeof(struct distree));
     for(i=0;i<26;i++)
         root->child[i] = 0;
     root->n = 0;
     while (gets(ch),strcmp(ch,""))
         Ins(ch);
     while (gets(ch))
         printf("%d/n",find(ch));

  return 0;
 } 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值