题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5455
题目大意:定义递推式 F为f(0)='f',f(1)='ff',f(2)='cff',f(n)=f(n-1)+'f',给出一个首位相连的字符串s,问组成s至少需要多少个F,如果F不能组成s,输出-1.
分析:很明显我们有:
(1)如果字符串含有除c和f外的其他字符的话,那么输出-1,如果3倍c的数量大于字符串s的长度,也输出-1.
(2)如果字符串只含有f,那么结果为(len+1)/2,len为字符串s的长度.
(3)对于其他情况,我们纪录每一个c出现的位置,然后从后往前遍历,如果c[i]-c[i-1]>2的话,那么就说明这两个c之间含有大于等于2个的f,计数器加1,否则标记不可能.
对于第一个c之前和最后一个c之后的部分,如果相加有大于等于2个f的话,(同样这一步也可以判断如果只有一个c的话并且c[0]+len-c[k-1]>2也就是字符串s长度大于2)计数器再加1,否则标记不可能。
实现代码如下:
#include <cstdio> #include <cstring> #include <iostream> #include <cmath> #include<vector> #include<queue> #include<algorithm> using namespace std; typedef long long LL; const int maxn=1000005; const int INF=0x3f3f3f3f; char str[maxn]; int cnt[maxn]; int main() { int T, cas=1; scanf("%d", &T); while(T--) { scanf("%s", str); int len=strlen(str); int k=0; int flag=1; for(int i=0; i<len; i++) { if(str[i]=='c')cnt[k++]=i; if(str[i]!='c'&&str[i]!='f')flag=0; } printf("Case #%d: ", cas++); if(!flag || k*3>len) { puts("-1"); continue; } if(!k) { printf("%d ", (len+1)/2); continue; } int ans=0; for(int i=k-1; i>0; i--) { if(cnt[i]-cnt[i-1]>2)ans++; else { flag=0; break; } } ///对于第一个c之前和最后一个c之后的部分, ///如果相加有大于等于2个f的话,(同样这一步也可以判断如果只有一个c的话并且c[0]+len-c[k-1]>2也就是字符串s长度大于2)计数器再加1, if(cnt[0]+len-cnt[k-1]>2)ans++; else flag=0;///否则标记不可能 if(flag)printf("%d ", ans); else puts("-1"); } return 0; }