Наивный алгоритм: используя два вложенных цикла, проверить все подстроки, являются ли они палиндромами. Такой алгоритм будет работать O(|S|^2), что при ограничении |S| <= 10^5 потребует примерно 10^10 / 2 сравнений, что достаточно долго.
Оптимизация: в центре у палиндрома четной длины всегда пара одинаковых символов. Их можно найти, а затем увеличивать длину до тех пор, пока это возможно. Плюс этого наблюдения в том, что если пара попадется не в центре, то максимальная длина подстроки-палиндрома с центром в этой паре, будет ограничена сверху. Однако в худшем случае (все символы одинаковы) всё равно придется произвести немалое число сравнений.
Однако задачу можно решить и за линейное время. Например, существует алгоритм Манакера, основанный на том, что можно использовать информацию, что часть строки является палиндромом. А именно, если в длинную-длинную строку-палиндром входит другая подстрока-палиндром, то можно не начинать проверку заново, а использовать уже имеющуюся информацию.
Пример 1: "длинная" подстрока-палиндром: cbbaabbaabbc в которой известна подстрока-палиндром. Тогда в строке есть симметричная подстрока-палиндром: cbbaabbaabbc Пример 2: "длинная" подстрока палиндром: bbaabbaabbaa Зная, что в ней есть подстрока-палиндром bbaabbaabbaa, можно явные сравнения для подстроки с центром в bbaabbaabbaa начинать уже с bbaabbaabbaa
Если не хочется писать самостоятельно, алгоритм Манакера легко находится.
int main() { int a[50][2]; int n; int k1=0; int k2=0; int k3=0; int k4=0; cin >> n; for (int i = 0; i < n; i++) { cin >> a[i][0] >> a[i][1]; } for (int i = 0; i < n; i++) { if (a[i][1]>0) if (a[i][0]>0) k1++; else k2++; else if (a[i][0]>0) k4++; else k3++; } if ((k2>=3)or(k2==2)and(k1>3)or(k3>5)or(k4>9)) cout << "Clock is broken" << "\n"; else cout << k2 << k1 << ":" << k3 << k4 << "\n"; return 0; }
Who
Объяснение:
--₸/₸(₸&(₸(₸-₸6₸-#-₸:₸!''()'8'