hdu---5455---fang fang

题目链接: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;
}
原文地址:https://www.cnblogs.com/w-y-1/p/5772138.html