题目地址:点击打开链接
题意:给你一个字符串首尾相接问最少能由几个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);
}
}