1、 主要是第三个条件:要不能有重复的子串且子串的长度>2,这一点 可以转为为最小长度=3的子串是否在字符串中存在重复;这样就很好解决了,将所有字串存储在set中直接查找重复的字串;

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

int main()
{
    string str;
    while (cin >> str) {
        string tmp = str;
        int len = tmp.length();
        if (len <= 8) {  // 长度8
            cout << "NG" << endl;
            continue;
        }
        multiset<string> strset;
        int count[4] = {0, 0, 0, 0};
        for (int i = 0; i < len; i++) {
            if (tmp[i] >= 'a' && tmp[i] <= 'z') {
                count[0] = 1;
            } else if (tmp[i] >= 'A' && tmp[i] <= 'Z') {
                count[1] = 1;
            } else if (tmp[i] >= '0' && tmp[i] <= '9') {
                count[2] = 1;
            } else {
                count[3] = 1;
            }
            strset.insert(tmp.substr(i, 3));  // 截取长度3的子串
        }
        if (count[0] + count[1] + count[2] + count[3] < 3) {  // 至少3种字符组合
            cout << "NG" << endl;
            continue;
        }
        bool flag = false;
        for(auto it : strset) {
            int cnt = strset.count(it);
            if (cnt >= 2) {
                flag = true;
                break;
            }
        }
        if (flag) {  // 重复子串
            cout << "NG" << endl;
            continue;
        }
        cout << "OK" << endl;
    }
    return 0;
}