码迷,mamicode.com
首页 > 其他好文 > 详细

[编程之美]资格赛 B Palindrome

时间:2015-04-18 13:10:38      阅读:162      评论:0      收藏:0      [点我收藏+]

标签:编程之美   二进制   c++   c   算法   

既然这个是资格赛,  时间也比较充裕, 我就讲解一下我做题的过程

Time Limit:2000ms
Case Time Limit:1000ms
Memory Limit:256MB

Description

Given a string, calculate the number of subsequences that are palindrome. A palindrome is a sequence of characters that reads the same backward or forward. For example, in the string “aba”, there are 7 subsequences "a", "b", "a", "ab", "aa", "ba", "aba". Only "a", "b", "a", "aa", "aba" are palindrome. Two subsequences that contain characters from different positions are considered different.

Input

The first line of input contains a single integer T specifying the number of test cases.  In each test case, there is only one line containing a string.

Output

For each test case, output a line containing "Case #X: Y", where X is the test case number starting from 1, followed by one integer Y indicating the number of palindrome subsequences. Output the answer modulo 100007.

Limits

1 ≤ T ≤ 30

Small

Length of string ≤ 25

Large

Length of string ≤ 1000

Sample Input
5
aba
abcbaddabcba
12111112351121
ccccccc
fdadfa
Sample Output
Case #1: 5
Case #2: 277
Case #3: 1333
Case #4: 127
Case #5: 17

我最先想到的就是枚举法了,  把所有的子列都列举出来, 一一判断它们是不是回文串

枚举的方法即使用二项式, 通过二进制数判断哪些字符应当出现在子列中:

#include <iostream>
#include <string>
using namespace std;

int main(void){
	int T,count=0;
	cin >> T;

	int result[30];
	for (int mem = 0; mem < 30; mem++)
	{

		result[mem] = 0;
	}
	while (count<T)
	{
		char a[1000];
		cin >> a;
		int g = 0;
		while (a[g]!='\0')
		{
			g++;
		}
		int size = g;
		for (int i = 1; i < 1<<size; i++)
		{
			//string sub;
			char* sub;
			sub = (char*)malloc(size*sizeof(char));
			int appear = 0;
			for (int j = 0; j < size; j++)
			{
				
				if ((1 << j)&i){
					sub[appear++] = a[j];
				}
			}
			bool ok = true;
			int ii = 0;
			int jj = appear;
			for (int k = 0; ii <= (int)(jj/2); ii++)
			{
				if (sub[ii]!=sub[jj+k-ii-1])
				{
					ok = false;
				}
			}
			if (ok)
			{
				result[count]++;
			}
		}
		count++; 
	}
	count = 1;
	while (count<=T)
	{
		std::cout <<"Case #"<<count<<": "<< result[count-1] << endl;
		count++;
	}
	return 0;
}
带入sample 是测试成功的, 但是提交之后显示time limited exceeded

想想枚举法, 最大字符串有 长度为1000, 那我要枚举2^1000次, 早就溢出了,  

所以思考更高效的算法

将相同的字符两两配对, 组成一组, 利用递归的思想, 思考这两字符之间有几个其他的字符对

#include <iostream>
#include <string>
#include <vector>

using namespace std;

char a[1000];

int findPalindrome(int floor, int ceil){
	int result = 0;
	for (int i = floor; i <= ceil; i++)
	{
		for (int j = i; j <= ceil; j++)
		{
			if (a[i]==a[j])
			{
				if (i == j || i + 1 == j)
				{
					result += 1;
				}
				else
				{
					result++;
					result += findPalindrome(i+1, j-1);
				}
			}
		}
	}
	return result;
}

int main(void){
	int T, count = 0;
	cin >> T;
	
	int result[30];
	for (int mem = 0; mem < 30; mem++)
	{
		result[mem] = 0;
	}
	while (count<T)
	{
		for (int i = 0; i < 1000; i++)
		{
			a[i] = '\0';
		}
		cin >> a;
		int g = 0;
		while (a[g] != '\0')
		{
			g++;
		}
		result[count] = findPalindrome(0, g-1);
		count++;
	}
	count = 1;
	while (count <= T)
	{
		std::cout << "Case #" << count << ": " << result[count - 1] << endl;
		count++;
	}
	return 0;
}
Accept


本人才疏学浅, 欢迎大家与我交流.

[编程之美]资格赛 B Palindrome

标签:编程之美   二进制   c++   c   算法   

原文地址:http://blog.csdn.net/qq_21970857/article/details/45112067

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!