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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章