hdu 4821
来源:互联网 发布:3d动画软件 编辑:程序博客网 时间:2024/06/06 04:10
题意:就是有一个字符串S,要求找到符合以下几种情况S的子串的个数.
情况1: 该子串的长度为L*M
请况2: 该子串的字串被分为M个,在该M个子子串中不存在相同.
(子串不同:出发的下标不同)
解题思路:
对于该问题的核心有两点:因为总串的长度比较大,所以判段字符串时否出现相同,不可能用平常的比较方法,第二如何判断两个相同的字符串到底在那个子串中。
对于第一点,我们可以用字符串hash函数来解决。
对于第二点,我们先算出下标[0,L)的所有子串的请况,那么[L,|s|- L*M]的请况可以根据之前算过的来推出。
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <string>#include <vector>#include <map>#include <math.h>using namespace std;#define MAXSZ 100010#define MOD 100003typedef unsigned int ul;typedef struct node{ node(){ } node(ul hanum){ //s = key; hashnum = hanum; } // string s; ul hashnum;};bool vis0[MAXSZ],vis1[MAXSZ];char str[MAXSZ];int hasharr[MAXSZ],cnt,indexs[MAXSZ];int M,L;node vt[MAXSZ];vector<int>vt1[MAXSZ];map<int,int>mp[MAXSZ];//inline ul BKDRHash(char *str){// ul seed = 31; // 31 131 1313 13131 etc..// ul hash = 0;//// while (*str)// {// hash = hash * seed + (*str++);// }//// return (hash & 0x7FFFFFFF);//}void init(){ cnt = 0; //memset(ff,0,sizeof(ff)); //memset(vis2,0,sizeof(vis2)); for(int i=0;i<MAXSZ;++i){ if(mp[i].size()){ mp[i].clear(); } }}int hashit(char *key,ul hashnum){ int ind = hashnum%MOD; while(vis0[ind]){ if(vt[ind].hashnum!=hashnum){ ind++; }// else if(vt[ind].s!=key){// ind++;// } else break; if(ind==M){ ind%=M; } } if(!vis0[ind]){ //vt[ind].s = key; vt[ind].hashnum = hashnum; vis0[ind] = true; hasharr[cnt++] = ind; } return ind;}void prepro(){ char *p0 = str; char *p1 = str; char cc; ul hash = 0; ul seed = 31; ul hashnum; ul tmphs0; int ind = 0,ind1 = 0; tmphs0 = 1; for(;ind<L;++ind){ hash = hash*seed +(*p1++); //hash %= MOD; if(ind){ tmphs0 = (tmphs0*seed); } } hashnum = hash&0x7FFFFFFF; //cc = (*p1); //(*p1) = 0; //ind = hashit(p0,hashnum); //(*p1) = cc; //vt1[ind].push_back(0); indexs[0] = hashnum; while(*p1){ hash = ((hash - tmphs0*(*p0++))); hash = (hash*seed +(*p1++)); cc = (*p1); ++ind1; // (*p1) = 0; // ind = hashit(p0,hash&0x7FFFFFFF); //(*p1) = cc; //vt1[ind].push_back(ind1); indexs[ind1] = hash&0x7FFFFFFF; } }int solve(){ // memset(vis1,false,sizeof(vis1)); // memset(vis2,false,sizeof(vis2)); int len = (int)strlen(str); int ans ; int sz; int tmp0,tmp1,tmp2,tmp3,tmp4,tmp5,tmp6; int up = len - (L*M); ans = 0;// for(int i=0;i<cnt;++i){// tmp0 = hasharr[i];// sz = (int)vt1[tmp0].size();// for(int j=0;j<sz;++j){// for(int k=j+1;k<sz;++k){// tmp3 = vt1[tmp0][j];// tmp4 = vt1[tmp0][k];// tmp1 = (tmp4 - tmp3);// if(tmp1%L==0){// tmp2 = tmp1/L;// if(tmp2+1<=M){// for(int h=0;h<=up;++h){// if(h>tmp3)break;// if((tmp3-h)%L==0&&(tmp4-h)%L==0){// //tmp5 = (tmp3-h)/L+1;// //tmp6 = (tmp4 - h)/L+1;// // if(!vis1[h]){// vis1[h] = true;// --ans;// }// }// }// }// }// }// }// } for(int i=0;i<L&&i<=up;++i){ //int ss = 0; for(int k=i,j=0;j<M;++j,k+=L){ tmp0 = indexs[k]; if(mp[i].count(tmp0)){ //++vis2[tmp0]; ++mp[i][tmp0]; //--ans; //break; } else { // ++ans; // ff[ss++] = tmp0; //++ff[i]; //++vis2[tmp0] ; mp[i].insert(pair<int,int>(tmp0,1)); } } if(mp[i].size()==M){ ++ans; } } int ML = (M-1)*L; for(int i=L;i<=up;++i){ tmp2 = i%L; tmp0 =indexs[i-L]; --mp[tmp2][tmp0]; //--vis2[tmp0]; //if(!vis2[tmp0]) //ff[i] = ff[i-L]; if(!mp[tmp2][tmp0]){ mp[tmp2].erase(tmp0); } //--ff[i]; tmp1 = ML; tmp0 = indexs[i+ML]; if(mp[tmp2].count(tmp0)){ // ++vis2[tmp0]; ++mp[tmp2][tmp0]; } else { //[tmp0]; mp[tmp2].insert(pair<int,int>(tmp0,1)); //++ff[i]; // ++ans; if(mp[tmp2].size()==M){ ++ans; } } } return ans;}void clear(){// for(int i=0;i<cnt;++i){// if(vt1[i].size()){// vt1[i].clear();// }// }}int main(){ // for(int i=100000;;++i){// bool flag = true;// for(int j=2;j<=sqrt(i*1.0);++j){// if(i%j==0){// flag = false;// break;// }// }// if(flag){// printf("%d\n",i);// break;// }// } while(scanf("%d%d",&M,&L)!=EOF){ init(); scanf("%s",str); prepro(); int ans = solve(); printf("%d\n",ans); // clear(); } return 0;}
0 0
- hdu 4821
- hdu 4821
- Hdu 4821 String
- HDU 4821 String
- hdu 4821 String
- HDU 4821 String
- HDU 4821 String
- hdu 4821 String
- HDU 4821 String
- HDU 4821 Hash
- HDU 4821 (哈希)
- hdu-4821-String-HASH
- HDU 4821 字符串hash
- HDU 4821 String hash
- hdu 4821 String(hash)
- hdu 4821(字符串hash)
- hdu 4821 string(哈希)
- hdu
- 全栈JavaScript之路(十二)了解 Selector API
- mybatis
- K-means聚类算法
- IplImage和cv::Mat的转化
- 线段树ADT
- hdu 4821
- jQuery 模块拖动,拖动层效果
- 初探C++ 深拷贝与浅拷贝
- 震荡波病毒C语言源码
- Ext.Window及其相关组件
- poj 2154 Color 欧拉函数优化的ploya计数
- 机房收费系统重构(五)—登陆窗体完整版
- obj-c编程16:键值编码(KVC)
- 非常愤怒:美军侦察机飞临中国981平台最近仅200米