单词测试

Description

给定一个由英文字母组成的字符串,求出一个子串,满足如下要求:该子串所包含的元音字母(a,e,i,o,u)的个数不大于辅音字母的个数的两倍。
你的任务是找到最长的满足要求的子串,输出其长度,并且输出最长的满足条件的子串的个数(区分2个子串是否不同的因素是起始位置和长度)。

Input

输入包括多组数据,每组数据包括一行,每行有一个由英文字母组成的字符串(长度<=200000)。

Output

每组数据输出一行,每行包括2个整数a和b,其中a代表最长子串的长度,b代表最长子串的个数,若不存在这样的子串,则输出“No solution”(不含引号)。

Sample Input

abo
oeis

Sample Output

3 1
3 1

题目链接:http://edu.freefcw.com/problem/show/1594

写了一个最笨的O(n^2)的算法,看到题目中的“长度<=200000”一直不敢提交,认为一定会TLE,想降低复杂度,但是又想不出方法,还是算法功底太弱了。

后来一咬牙,豁出去了,不就是TLE吗,又不会怀孕,提交试试看吧。这次结果WA了,想着可能是字符串中出现了大写字母而程序没有对其进行处理导致的,修改之后再次提交。

结果让我很惊讶,居然AC了,耗时还是0ms,是OJ上的测试用例不靠谱呢还是题目故意吓唬人呢?

先mark一记,想出好方法了再添加上来。如果某位大牛有好的算法,还望不吝赐教,不胜感谢!

#include <stdio.h>
#include <memory.h>
#define MAX 200001

int main(void)
{
	char str[MAX];
	int status[128];
	int i, j, len_1, len_2, len_3, len_4, max_len, count;

	memset(status, 0, sizeof(status));
	status['a'] = status['A'] = 1;
	status['e'] = status['E'] = 1;
	status['i'] = status['I'] = 1;
	status['o'] = status['O'] = 1;
	status['u'] = status['U'] = 1;

	while (scanf("%s", str) != EOF)
	{
		i = max_len = count = 0;
		while (str[i] != '\0')
		{
			j = i;
			len_1 = len_2 = len_3 = len_4 = 0;
			while (str[j] != '\0')
			{
				if (status[str[j]] == 0)
				{
					++len_1;
				}
				else
				{
					++len_2;
				}
				++len_3;

				if (len_2 - len_1 <= len_1 && len_4 < len_3)
				{
					len_4 = len_3;
				}
				++j;
			}
			
			if (len_4 > max_len)
			{
				max_len = len_4;
				count = 1;
			}
			else if (len_4 == max_len && len_4 != 0)
			{
				++count;
			}
			else
			{
			}

			if (len_4 == len_3)
			{
				break;
			}

			++i;
		}

		if (count == 0)
		{
			printf("No solution\n");
		}
		else
		{
			printf("%d %d\n", max_len, count);
		}
	}
	
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值