1.求最长回文子序列: 我的想法是2重for遍历string的子序列用assign(s.begin() + i, s.begin() + j) 求子序列,但是貌似复杂度太高。。再想想
2.2重for的复杂度到了O(n^3),重复的判断太多,改为枚举中心对称点:对于N的string 就有2N-1个中心对称点,从左右开始判断即可,O(n^2)
3.继续WA,还好有样例给出,'\n'符的判断也很重要
/*
ID: zhangw31
PROG: calfflac
LANG: C++
*/
#include <iostream>
#include <cctype>
#include <string>
#include <cstring>
#include <fstream>
using namespace std;
string s;
string b;
string answer;
string tmp;
int t[20005];
int cr[20005];
int len, maxlen, left1, right1;
void longPalindrom(int i, int j) {
while(i >= 0 && j < len) {
if (b[i] != b[j]) break;
else {i--; j++;}
}
if (j - i - 1 > maxlen) {
maxlen = j - i - 1;
left1 = t[i + 1];
right1 = t[j - 1];
}
}
int countalpha(string s) {
int len = s.length();
int a = 0;
for (int i = 0; i < len; i++) {
if (isalpha(s[i])) a++;
}
return a;
}
int main() {
ifstream fin("calfflac.in");
ofstream fout("calfflac.out");
while(getline(fin, tmp)) {
s += tmp;
cr[s.length()-1] = 1;
}
len = s.length();
int counter = 0;
for (int i = 0; i < len; i++) {
if (isalpha(s[i])) {
b += tolower(s[i]);
t[counter++] = i;
}
}
len = b.length();
for (int i = 0; i < len; ++i) {
longPalindrom(i-1, i+1);
longPalindrom(i, i+1);
}
fout << maxlen << endl;
for (int i = left1; i <= right1; ++i) {
fout << s[i];
if (cr[i] == 1) fout << endl;
}
if(cr[right1] != 1) fout << endl;
}