poj1159非标准回文串解题思路,然后又变的标准了

先声明,我这个解法并不是标准的回文串,但是在poj上一直是WA,所以总是哪里是有问题的,但是很尴尬的是,自己测试是没有问题的。。。
所以写出来自己梳理一下,如果哪位网友路过帮我看看也是非常非常之感谢

首先呢看一下题目要求的回文结构,最直接的想法就是遍历每一个字符,依次作为中心,然后看这种情况下所需补充的最少字符数
那如何计算最小字符数呢,我的想法是设立两个指针,分别指向对称中心左右两边,然后向外移动指针,通过对比指针指向判断是增加一个符号构成对称还是继续移动
所以最后的情况是至少有一个指针到达了边界,这个时候另一个指针剩下的符号就要全部插入以便构成回文,所以就有了以下的代码
#include <iostream>
#include <string>
using namespace std;

int main()
{
	string s;
	int len;
	int max;
	cin >> len;
	max = len - 1;
	cin >> s;
	for (int i = 1; i < len-1; i ++){
		int j = i-1, k = i+1, temp = 0;
		while(j>=0){
			while (k<len){
				if ( s[j] == s[k] ){
					j --; k ++;
				}
				else{
					k ++;
					temp ++;
				}
			}
			if (k>=len) break;
		}
		if ( j+1 ) temp += j + 1;
		if ( len-k ) temp += len - k;
		if ( temp<max ) max = temp;
	}
	cout << max << endl;
	return 0;
}
但是这个代码是有一点问题的,就是它是以一个数字为中心,两边对称的结构,这是不全面的,另一种情况是以两个数之间的空隙为中心,额这样可能不太好理解,举个例子
1233 以数为中心,最小插入为3,即构成1233321 / 1323231 / 3123213,但以空隙为中心,则最小插入为2,即构成123321
这个改起来也很方便,调整指针的位置就好了,代码如下
#include <iostream>
#include <string>
using namespace std;

int main()
{
	string s;
	int len;
	int max;
	cin >> len;
	max = len - 1;
	cin >> s;
	for (int i = 1; i < len-1; i ++){

		int j = i-1, k = i+1, temp1 = 0;
		while(j>=0){
			while (k<len){
				if ( s[j] == s[k] ){
					j --; k ++;
				}
				else{
					k ++;
					temp1 ++;
				}
			}
			if (k>=len) break;
		}
		if ( j+1 ) temp1 += j + 1;
		if ( len-k ) temp1 += len - k;

		j = i, k = i+1;
		int temp2 = 0;
		while(j>=0){
			while (k<len){
				if ( s[j] == s[k] ){
					j --; k ++;
				}
				else{
					k ++;
					temp2 ++;
				}
			}
			if (k>=len) break;
		}
		if ( j+1 ) temp2 += j + 1;
		if ( len-k ) temp2 += len - k;

		int temp = 0;
		if ( temp1>temp2) temp = temp2;
		else temp = temp1;
		if (temp<max) max = temp;
	}
	cout << max << endl;
	return 0;
}

我发的时候我以为自己已经解决了,可是tm提交了之后还是报错,真是拿衣服,现在还是WA我也是没辙了。。。
其实我觉得要是超时我都可以接受,毕竟将近N3的时间复杂度,可是WA哦我的天。。。
期待什么时候脑洞大开想出来吧

于是我又回来了,换了另一种方法。。。嗯。。。就是网上流传的那种。。。
具体的思路可以看他的文章啦,但是代码是我自己写的,大家也是看得出来的啦
#include <iostream>
#include <string>
using namespace std;

int main()
{
	int n;
	cin >> n;
	string s1;
	cin >> s1;
	string s2 = s1;
	for (int i = 0; i < n; i ++)
		s2[i] = s1[n-i-1];
	int c[2][5001];
	int temp = 0;
	memset(c,0,sizeof(c));
	for (int i = 1; i <= n; i ++)
		for ( int j = 1; j <= n; j ++){
			temp = c[(i-1)%2][j]>c[i%2][j-1]?c[(i-1)%2][j]:c[i%2][j-1];
			if (s1[i-1] == s2[j-1])
				c[i%2][j] = (c[(i-1)%2][j-1]+1)>temp?(c[(i-1)%2][j-1]+1):temp;			
			else
				c[i%2][j] = temp;
		}
	int max = c[0][n]>c[1][n]?c[0][n]:c[1][n];
	cout << n-max << endl;

	return 0;
}

所以那个AC是多么的不容易。。。
发布了32 篇原创文章 · 获赞 11 · 访问量 3万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章