Timus 1723. Sandro's Book 题解

It's been quite a number of years since Lich Sandro retired. Sometimes in the evenings, when he feels especially lonely, he takes a book that was presented to him by his student magicians on the occasion of his retirement.
This evening the great magician is also reading the book. One of the chapters describes Sandro's famous discovery: he invented a universal spell many years ago. Any substring (a few consecutive symbols of the string) of the universal spell is also a spell, and its power is equal to the number of times this spell is encountered in the universal spell (for example, the string “ue” encounters in the string “queue” twice, and the string “aba” encounters in the string “abababa” three times).
Sandro has a lot of free time now and he wants to find the most powerful spell. Help Sandro do it.

Input

The only input line contains the universal spell invented by Sandro. The spell is a non-empty string consisting of lowercase English letters with length at most50.

Output

Output any of the most powerful spells, according to Sandro's definition.

Sample

input output
tebidohtebidoh
tebidoh


本题就看故事, 故事看起来一长串, 理解起来也挺费力,所以一开始我使用KMP算法查找了所有子串:

#include <string>
#include <vector>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <map>
using namespace std;

class SandroBook
{
	vector<int> tbl;
	int encounter;
	string spell;
public:
	SandroBook():tbl(), encounter(0)
	{

	}

	int kmpSearch(string txt, string pat, int sta=0)
	{
		tbl.resize(pat.size());
		genTbl(pat);
		int c = 0;
		for (int i = 0, j = 0; i < txt.size(); i++)
		{
			if (pat[j] == txt[i]) j++;
			else if (j > 0)
			{
				j = tbl[j-1];
				i--;
			}
			if (pat.size() == j)
			{
				c++;
				j = tbl[j-1];
			}
		}
		return c;
	}

	void genTbl(const string &pat)
	{
		for (int i = 1, j = 0; i < pat.size(); i++)
		{
			if (pat[i] == pat[j]) tbl[i] = ++j;
			else if (j > 0)
			{
				j = tbl[j-1];
				i--;
			}
		}
	}
	void SandroRun()
	{
		string txt;
		cin>>txt;
		encounter = 0;
		for (int i = 0; i < txt.size(); i++)
		{
			for (int d = i+1; d < txt.size(); d++)
			{
				string pat = txt.substr(i, d-i+1);
				int c = kmpSearch(txt, pat, i+1) + 1;
				if (c > encounter)
				{
					encounter = c;
					spell = pat;
				}
			}
		}
		cout<<spell;
	}
};

上面程序可以AC。很sophisticated 的KMP算法。

但是后来一想,这个不对啊,子串包括了一个字母的子串,那么本题就太简单了,看起来甚至像是一个玩笑了。

经验证的确如此,因为下面程序也能通过。教训还是题意的问题,如果可以问,一定要先问清楚题意。大概本题出题者就是在开玩笑。

#include <iostream>
#include <stdio.h>

using namespace std;

int mainSandro()
{
	char str[50];
	int maxi,max,i=0;
	int ch[26]={0};

	scanf("%s",&str);
	while(str[i++]) ch[str[i]-'a']++;

	maxi=0;
	max=ch[maxi];

	for(i=1;i<26;i++)
	{
		if(ch[i]>max)
		{
			maxi=i;
			max=ch[maxi];
		}
	}
	printf("%c\n",maxi+'a');
	return 0;
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值