现在的位置: 首页 > 综合 > 正文

poj1200

2013年09月02日 ⁄ 综合 ⁄ 共 2205字 ⁄ 字号 评论关闭

此题堪称经典的hash啊。题目是给你一个字符串很长,给你子字符串的长度N和这个字符串中共有多少个不同的字符NC,求这个长的字符串有多少中长度为N的子字符串。

 

此题我已开始想的是map,不想超时。只能用这种方法。

在这个题上有一个技巧,就是由于题目没说字符串里面是什么字符,所以这里很巧妙的应用了ascll码作为数组下标变量。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define maxn 16000000

char s[maxn];
int a[10000];
int hash[maxn];

int main()
{
 int N,NC,num=0,len,i,cnt=0,sum=0,j;
 scanf("%d%d",&N,&NC);
 scanf("%s",&s);

 len=strlen(s);

 for(i=0;i<len;i++)//ascll码作为下标
 {
  if(!a[s[i]])
   a[s[i]]=++num;
 }

 for(i=0;i<len-N+1;i++)
 {
  sum=0;
  for(j=i;j<i+N;j++)
   sum+=sum*NC+a[s[j]];

  if(!hash[sum])
  {//hash表
   cnt++;
   hash[sum]=1;
  }
 }

 printf("%d/n",cnt);
 return 0;
}

 

 

此题让我想到了另外一题。

 

I. DNA序列检测(绿)

时间限制: 5秒  内存限制: 64M

问题描述

给定一个长度为N的字符串S(字符集为ACTG)和Q个询问,每个询问为一个长度不超过10的字符串T(字符集同样为ACTG)。对于每个询问,你需要回答T是否是S的一个子串(substring)。

输入格式

输入文件的第一行包含两个整数N和Q,含义如上文所示。(N,Q <=1000000)

接下来的一行包含一个长度为N的字符串,表示S。

接下来的Q行每行包含一个长度不超过10的字符串T。

输出格式

对于每个询问,如果T是S的子串的话,输出Yes,否则输出No。

输入样例

10 3
ACTGTGTGAC
ACT
ACTT
TGTG

输出样例

Yes
No
Yes

这两道题其实是一样的啊,如果当时我做过1200,这道题目就简单了,我当时还用KMP算法,bs!

代码:

  1. #include<stdio.h>  
  2. #include<string.h>  
  3. #include<math.h>   
  4.   
  5. char str[1000001];   
  6. int w[1000001];   
  7. int h[10000000];   
  8.   
  9. int main()   
  10. {   
  11.     int m,n,i,j,t,k,sum;   
  12.     char s[11];   
  13.     scanf("%d%d",&m,&n);   
  14.     scanf("%s",str);   
  15.     t=0;   
  16.     memset(h,0,sizeof(h));   
  17.     for(i=0;i<m;i++)   
  18.     {   
  19.         if(str[i]=='A')   
  20.             w[i]=1;   
  21.         else if(str[i]=='C')   
  22.             w[i]=2;   
  23.         else if(str[i]=='T')   
  24.             w[i]=3;   
  25.         else if(str[i]=='G')   
  26.             w[i]=4;   
  27.     }   
  28.     for(i=0;i<m;i++)   
  29.     {   
  30.         t=0;   
  31.         for(j=0;j<10&&(i+j)<m;j++)   
  32.         {   
  33.             t=t*4+w[i+j];   
  34.             h[t]=1;   
  35.         }   
  36.     }   
  37.     for(i=0;i<n;i++)   
  38.     {   
  39.         memset(s,0,sizeof(s));   
  40.         scanf("%s",s);   
  41.         j=strlen(s);   
  42.         sum=0;   
  43.         for(k=j-1;k>=0;k--)   
  44.         {   
  45.             if(s[k]=='A')   
  46.                 sum+=(int)pow(4.0,j-1-k);   
  47.             else if(s[k]=='C')   
  48.                 sum+=(int)(2*pow(4.0,j-1-k));   
  49.             else if(s[k]=='T')   
  50.                 sum+=(int)(3*pow(4.0,j-1-k));   
  51.             else if(s[k]=='G')   
  52.                 sum+=(int)(4*pow(4.0,j-1-k));   
  53.         }   
  54.         if(h[sum]==1)   
  55.             printf("Yes/n");   
  56.         else  
  57.             printf("No/n");   
  58.     }   
  59.     return 0;   
【上篇】
【下篇】

抱歉!评论已关闭.