第一轮

第一版(14/15)

#include <iostream>
using namespace std;

bool isOurPurpose(const string &a){
    // int x = a.size() / 2;
    for(int i = 0; i < a.size(); i++){
        if(a[i] != a[a.size() - 1 - i]){
            return false;
        }
    }
    return true;
}

int main() {
    string s;
    cin >> s;

    for(int k = s.size(); k >= 1; k--){
        for(int i = 0; i < s.size() - k; i++){
            if (isOurPurpose(s.substr(i, k))) {
                cout << k;
                return 0;
            }
        }
    }

}
// 64 位输出请用 printf("%lld")

第二版(AC)

#include <iostream>
using namespace std;

bool isOurPurpose(const string &a){
    // int x = a.size() / 2;
    for(int i = 0; i < a.size(); i++){
        if(a[i] != a[a.size() - 1 - i]){
            return false;
        }
    }
    return true;
}

int main() {
    string s;
    cin >> s;

    for(int k = s.size(); k >= 1; k--){
        for(int i = 0; i <= s.size() - k; i++){
            if (isOurPurpose(s.substr(i, k))) {
                cout << k;
                return 0;
            }
        }
    }

}
// 64 位输出请用 printf("%lld")

  1. 缺少一个用例,说明有边界情况没考虑到,最直观的边界情况就是输入的字符串只有一个字母。
  2. 代入发现在内循环的循环条件有问题,i应该是可以等于s.size() - k的。
  3. 实际上,i作为字符串数组的下脚标,其最大值一直都是两个窗口的长度差。可以在脑海中画两个窗口,窗口重合的时候,i就指向0的位置。
  4. 这题的方法和[[查找两个字符串的最长公共子串]]是相似的。

第二轮

第一版(AC)

#include <iostream>
using namespace std;

bool function_1(const string& s) {
    int l = s.size();
    if (l % 2 == 0) {
        for (int i = 0; i < l / 2; i++) {
            if (s[i] != s[l - i - 1]) return false;
        }
    } else {
        for (int i = 0; i < (l - 1) / 2; i++) {
            if (s[i] != s[l - i - 1]) return false;
        }
    }
    return true;
}

int main() {
    string s;
    cin >> s;

    for (int k = s.size(); k >= 1; k--) {
        for (int i = 0; i <= s.size() - k; i++) {
            string a = s.substr(i, k);
            if (function_1(a)) {
                cout << k << endl;
                return 0;
            }
        }
    }
}
// 64 位输出请用 printf("%lld")

  1. 自定义函数的命名:如果能想到合适的英文表达,当然直接用;如果想不到,按function_1function_2来命名就行。
  2. 回文字符串的判定:这里是把回文串的判定封装起来,时间复杂度为O(n^3),相比于第一轮的第二版,这里借鉴了中心扩展法的思想,但是时间复杂度没有改变。

第二版(中心扩展法,2/15)

#include <iostream>
using namespace std;

int function_1(const string& s) {
    int maxlen = 0;
    if (s.size() % 2 == 0) {
        for (int i = 0; i < s.size(); i++) {
            int left = i;
            int right = i + 1;
            int len = right - left + 1;
            while (s[left] == s[right]) {
                if(len >= maxlen) maxlen = len;
                if (left - 1 >= 0 && right + 1 <= s.size() - 1) {
                    left--;
                    right++;
                }
            }
        }
    } else {
        for (int i = 0; i < s.size(); i++) {
            int left = i;
            int right = i;
            int len = right - left + 1;
            while (s[left] == s[right]) {
                if(len >= maxlen) maxlen = len;
                if (left - 1 >= 0 && right + 1 <= s.size() - 1) {
                    left--;
                    right++;
                }
            }
        }
    }

    return maxlen;
}

int main() {
    string s;
    cin >> s;

    cout << function_1(s) << endl;

    return 0;
}
// 64 位输出请用 printf("%lld")

  1. 15个用例里面有2个测试通过,很可能是极端情况的2种。
  2. 经检查发现没有写更新len的代码,符合预判——不需要更新len的两种情况通过了。

第三版(中心扩展法,运行超时,11/15)

#include <iostream>
using namespace std;

int function_1(const string& s) {
    int maxlen = 0;
    if (s.size() % 2 == 0) {
        for (int i = 0; i < s.size(); i++) {
            int left = i;
            int right = i + 1;
            int len = right - left + 1;
            while (s[left] == s[right]) {
                len = right - left + 1;
                if(len >= maxlen) maxlen = len;
                if (left - 1 >= 0 && right + 1 <= s.size() - 1) {
                    left--;
                    right++;
                }
            }
        }
    } else {
        for (int i = 0; i < s.size(); i++) {
            int left = i;
            int right = i;
            int len = right - left + 1;
            while (s[left] == s[right]) {
                len = right - left + 1;
                if(len >= maxlen) maxlen = len;
                if (left - 1 >= 0 && right + 1 <= s.size() - 1) {
                    left--;
                    right++;
                }
            }
        }
    }

    return maxlen;
}

int main() {
    string s;
    cin >> s;

    cout << function_1(s) << endl;

    return 0;
}
// 64 位输出请用 printf("%lld")

  1. 程序未能在规定时间内运行结束,请检查是否循环有错或算法复杂度过大。
  2. 15个用例里面有4个测试没通过,很可能是极端情况的4种,而这4种情况陷入死循环导致超时了。
  3. 经检查发现while()语句可能出现死循环,符合预判——。

第四版(AC)

#include <iostream>
using namespace std;

int function_1(const string& s){
    int maxlen = 0;
    if (s.size() % 2 == 0) {
        for (int i = 0; i < s.size(); i++) {
            int left = i;
            int right = i + 1;
            int len = right - left + 1;
            while (s[left] == s[right]) {
                len = right - left + 1;
                if (len >= maxlen) maxlen = len;
                if (left - 1 >= 0 && right + 1 <= s.size() - 1) {
                    left--;
                    right++;
                } else if (left == 0 || right == s.size() - 1) {
                    break;
                }
            }
        }
    }else {
        for (int i = 0; i < s.size(); i++) {
            int left = i;
            int right = i;
            int len = right - left + 1;
            while (s[left] == s[right]) {
                len = right - left + 1;
                if (len >= maxlen) maxlen = len;
                if (left - 1 >= 0 && right + 1 <= s.size() - 1) {
                    left--;
                    right++;
                } else if (left == 0 || right == s.size() - 1) {
                    break;
                }
            }
        }   
    }
    return maxlen;
}

int main() {
    string s;
    cin >> s;

    cout << function_1(s) << endl;

    return 0;
}
// 64 位输出请用 printf("%lld")