HDU 5455 Fang Fang(字符串模拟)

本文探讨了一道关于字符串处理的问题,重点在于如何通过判断特定字符间的距离来确定最少需要多少个F子串来构成首尾相连的字符串。文章提供了详细的解题思路及AC代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目地址:点击打开链接

题意:给你一个字符串首尾相接问最少能由几个F子串给出构成,F子串的定义如题

思路:需要注意的就几点(1)2个c之间的f数不能少于2(2)s字符串中不能有别的字符(3)假如第一个字符为f则,最后一个c字符后面的f加上最前面的f字符的数量不能少于2,假设第一个字符不为f,则最后一个c字符后面的f字符数量不能少于2(4)全是f字符的情况,网赛的时候少考虑只有一个f的特殊情况,wrong了无数发,下来仔细想的时候5分钟就A了,都是泪啊

AC代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cstring>
#include <climits>
#include <cmath>

using namespace std;

const int maxn = 1e6 + 10;
char s1[maxn];
int visit[maxn];

int main()
{
    int t,i,cas = 1;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%s",s1);
        int n = strlen(s1);
        int flag = 0,sum = 0,k = 0;
        int flag2 = 0;
        if(s1[0] == 'f')
            flag = 1;
        for(i=0; i<n; i++)
        {
            if(flag)
            {
                sum++;
            }
            if(s1[i] == 'c')
            {
                visit[k++] = i;
                flag = 0;
            }
            if(s1[i] != 'c' && s1[i] != 'f')
            {
                flag2= 1;
            }
        }
        if(flag2)//有别的字符直接退出
        {
            printf("Case #%d: -1\n",cas++);
            continue;
        }
        for(i=k-1; i>0; i--)
        {
            if(visit[i] - visit[i-1] < 3)
            {
                flag2 = 1;
                break;
            }
        }
        if(flag2)//2个c字符之间的f字符数量小于2,直接退出
        {
            printf("Case #%d: -1\n",cas++);
            continue;
        }
        if(s1[0] == 'f' && sum - 1 + n - 1 - visit[k-1] < 2)//第一个字符为f,则最前面字符的数量加上最后一个c字符后面的f数量的个数小于2,直接退出
        {
            flag2 = 1;
        }
        if(s1[0] == 'f' && n == 1)//只有一个f字符时要特判一下,害的我wrong了无数发
        {
            flag2 = 0;
        }
        if(s1[0] != 'f' && n - 1 - visit[k-1] < 2)//第一个字符不为f,则最后一个c字符后面的f字符的数量小于2,直接退出
        {
            flag2 = 1;
        }
        if(flag2)
        {
            printf("Case #%d: -1\n",cas++);
            continue;
        }
        if(k == 0)//全是f字符的情况
        {
            if(n % 2 == 0)
               k = n / 2;
            else
                k = n / 2 + 1;
        }
        printf("Case #%d: %d\n",cas++,k);
    }
}

学长代码:

思路差不多

#include<iostream>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<cstdio>

using namespace std;

char  str[1000010];
char str2[1000010];

int main()
{
    int t;
    int i,len;
    int cnt;
    int ca = 1;
    int ans;
    bool flag;
    scanf("%d",&t);
    while(t--)
    {
        flag = true;

        scanf("%s",str);
        len = strlen(str);
        int temp = -1;
        cnt = 0;
        for(i = 0; i < len; i++)
        {
            if(str[i] == 'c')
            {
                temp = i;
                break;
            }
            if(str[i] != 'c' && str[i] != 'f')
                flag = false;

        }

        if( !flag )
        {
            printf("Case #%d: -1\n",ca++);
            continue;
        }

        if(temp == -1)
        {
            int tmp = len / 2;
            if(len %  2 != 0)
                tmp++;
            printf("Case #%d: %d\n",ca++,tmp);
            continue;
        }


        for(i = temp; i < len; i++)
        {
            str2[cnt++] = str[i];
        }

        for(i = 0; i < temp; i++)
        {
            str2[cnt++] = str[i];
        }

        str2[cnt] = '\0';

        int Count = 0;

        ans = 0;

        for(i = 0; i < len; i++)
        {
            if(str2[i] == 'c' && i != 0)
            {
                if(Count >= 2)
                    ans++;
                else
                    flag = false;
                Count = 0;
            }
            if(str2[i] != 'c')
            {
                Count++;
            }
        }

        if(Count >= 2)
            ans++;
        else
            flag = false;
        if(flag)
            printf("Case #%d: %d\n",ca++,ans);
        else
            printf("Case #%d: -1\n",ca++);
    }
    return 0;
}

错误代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cstring>
#include <climits>
#include <cmath>

using namespace std;

const int maxn = 1e6 + 10;
char s1[maxn];
int visit[maxn];

int main()
{
    int t,i,cas = 1;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%s",s1);
        int n = strlen(s1);
        int flag = 0,sum = 0,k = 0;
        int flag2 = 0;
        if(s1[0] == 'f')
            flag = 1;
        for(i=0; i<n; i++)
        {
            if(flag)
            {
                sum++;
            }
            if(s1[i] == 'c')
            {
                visit[k++] = i;
                flag = 0;
            }
            if(s1[i] != 'c' && s1[i] != 'f')
            {
                flag2= 1;
            }
        }
        for(i=k-1; i>0; i--)
        {
            if(visit[i] - visit[i-1] < 3)
            {
                flag2 = 1;
                break;
            }
        }
        if(s1[0] == 'f' && sum - 1 + n - 1 - visit[k-1] < 2)
        {
            flag2 = 1;
        }
        if(s1[0] != 'f' && n - 1 - visit[k-1] < 2)
        {
            flag2 = 1;
        }
        if(k == 0)
        {
            if(n % 2 == 0)
               k = n / 2;
            else
                k = n / 2 + 1;
        }
        if(flag2)
        {
            k = -1;
            printf("Case #%d: %d\n",cas++,k);
        }
        else
            printf("Case #%d: %d\n",cas++,k);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值