这题思路不难, 比赛的时候没时间想了,唉。。。
而且我在做的时候还错误的理解了题意,我以为是在【a,b】的子串中,判断最长的【c,d】。结果想了很久,想到脑子都快炸了,想出来后发现样例有问题,然后才发现我个2B题意又读错了。其实是在【a,b】中删除一些元素得到最大的 【c,d】,这样子就更好做了。
解法: 首先可以知道的是,如果要在一个字符串s中删除一些元素的得到最多的连续的t串,那么我们可以采用贪心的策略,从头到尾扫一遍,用两个指针分别指向s和t,如果s[i]==t[j],这i++,j++,否则i++.
有了这个性质之后,就可以知道一个a可能有多个b,也可能没有b,但是可以知道的是,这个里面是有循环的, 然后就是找出循环结,就可以了
说的很是不清楚,还是看代码来的清晰把
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <algorithm> #include <math.h> #include <map> #include <queue> #include <sstream> #include <iostream> using namespace std; #define INF 0x3fffffff #define N 110 char stra[110]; char strb[110]; int mark[110]; int g[11000]; // fuck! 看错题还想的这么开心 int main() { //freopen("//home//chen//Desktop//ACM//in.text","r",stdin); //freopen("//home//chen//Desktop//ACM//out.text","w",stdout); int b,d; scanf("%d%d",&b,&d); scanf("%s",stra); scanf("%s",strb); int lena=strlen(stra); int lenb=strlen(strb); memset(mark,-1,sizeof(mark)); mark[0] = 0; int pos=0; int key=0; int cnt=0; //多少个A产生一次循环 int num=0; // 一个循环产生多少个B串 for(int ii=1;ii<=1000;ii++) { int sum=0; for(int i=0;i < lena;i++) { if(stra[i] == strb[pos]) { pos++; if(pos==lenb) { sum++; pos = 0; } } } g[ii] = sum; if(mark[pos]==-1) mark[pos]=ii; else { key = mark[pos]; cnt = ii - key; for(int ti=key+1;ti<=ii;ti++) num+=g[ti]; break; } } int ans = 0; if(b <= key) { for(int i=1;i<=b;i++) ans+=g[i]; } else { int tb=(b-key)/cnt; int tt=(b-key)-tb*cnt; for(int i =1 ;i<=key;i++) ans += g[i]; ans += tb*num; for(int i=key+1;i<=key+tt;i++) ans+=g[i]; } printf("%d\n",ans/d); return 0; }