улучши код и исправь все ошибки в алгоритме #inclu...

Creato il: 25 agosto 2026

Risposto usando GPT-5.6 Thinking da Chat01

Domanda

улучши код и исправь все ошибки в алгоритме
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
int main()
{
string str1, str2;
int n, cofp =0, ydl =0, dob =0;
long long ball =0;
cin >>n;
for (int l=0; l<n; l++) {
int ind =0;
ydl =0;
dob =0;
cofp =0;
int plox =0;
cin >> str1 >> str2;
int size1 = str1.size();
int size2 = str2.size();

text
if (str1 == str2 && ind ==0) { ball +=10; ind =1; } for (int i =0; i <size2; i++) { if (str1[i] ==str2[i] ) { cofp +=1; } else if (str2 [i] == str1[i-1] && i>=1) {// удл ydl +=1; } else if ( str2[i] == str1[i+1] && size1 <=i +1) { dob +=1; } } if ((cofp + ydl -1 == size1 && ind ==0 && str1[-1] == str2[-1]) || (ydl == min(size1, size2) && ind ==0)) { ball +=9; ind =1; } if((size1 -cofp ==1 && ind ==0 && size1 - size2 ==1 && cofp !=0)|| (size1 - size2 ==1 && ind ==0 && cofp !=0)) { ball +=9; ind =1; } if (size1 == size2 && cofp == (size1 -1) && ind ==0) { ball +=9; ind =1; }

}

cout << ball;
}

Risposta

Судя по логике программы, ты хочешь начислять:

  • 10 баллов, если строки полностью совпадают;
  • 9 баллов, если одну строку можно получить из другой одной операцией: удалить символ, добавить символ или заменить символ;
  • 0 баллов во всех остальных случаях.

В текущем коде есть несколько выходов за границы строки и сама проверка удаления/добавления работает неверно. Гораздо надёжнее не считать cofp, ydl, dob, а отдельно проверить, отличаются ли строки ровно на одно редактирование.

Исправленный и упрощённый вариант

cpp
#include <iostream> #include <string> #include <cstdlib> using namespace std; // Проверяет, можно ли превратить одну строку в другую // ровно одной операцией: вставка, удаление или замена. bool oneEdit(const string& a, const string& b) { int n = a.size(); int m = b.size(); // Если длины отличаются больше чем на 1, // одной операцией получить строку невозможно. if (abs(n - m) > 1) return false; // Одинаковая длина -> возможна только замена одного символа. if (n == m) { int differences = 0; for (int i = 0; i < n; ++i) { if (a[i] != b[i]) { ++differences; if (differences > 1) return false; } } return differences == 1; } // shorter всегда будет более короткой строкой. const string& shorter = (n < m ? a : b); const string& longer = (n < m ? b : a); int i = 0; int j = 0; int differences = 0; while (i < (int)shorter.size() && j < (int)longer.size()) { if (shorter[i] == longer[j]) { ++i; ++j; } else { ++differences; if (differences > 1) return false; // Пропускаем один символ в длинной строке. ++j; } } // Разница длин уже равна 1, поэтому оставшийся // символ в конце longer тоже является одной операцией. return true; } int main() { int n; cin >> n; long long ball = 0; for (int test = 0; test < n; ++test) { string str1, str2; cin >> str1 >> str2; if (str1 == str2) { ball += 10; } else if (oneEdit(str1, str2)) { ball += 9; } } cout << ball; return 0; }

Какие ошибки были в исходном коде

Самая опасная строка:

cpp
if (str1[i] == str2[i])

Цикл идёт до size2:

cpp
for (int i = 0; i < size2; i++)

но str1 может быть короче str2. Например:

text
str1 = "abc" str2 = "abcd"

при i == 3 происходит обращение к:

cpp
str1[3]

а такого символа нет. Это undefined behavior.

Здесь тоже ошибка:

cpp
str2[i] == str1[i-1] && i >= 1

Проверять границу нужно до обращения к массиву:

cpp
i >= 1 && str2[i] == str1[i - 1]

Потому что при i == 0 твой вариант сначала пытается выполнить:

cpp
str1[-1]

и только потом проверяет i >= 1.

А здесь:

cpp
str2[i] == str1[i+1] && size1 <= i + 1

условие границы написано наоборот. Для доступа к str1[i + 1] должно выполняться:

cpp
i + 1 < size1

причём проверка опять должна стоять первой:

cpp
i + 1 < size1 && str2[i] == str1[i + 1]

Наконец, это:

cpp
str1[-1] == str2[-1]

в C++ не означает последний символ строки. Отрицательных индексов здесь нет. Последние символы получают так:

cpp
str1.back() str2.back()

или:

cpp
str1[str1.size() - 1] str2[str2.size() - 1]

Но в исправленном алгоритме такая проверка вообще не нужна.

Например, новый код корректно обработает:

text
abc abc -> 10 // совпадение abc abd -> 9 // замена abc abcd -> 9 // добавление abcd abc -> 9 // удаление abc axcd -> 0 // нужно больше одной операции

Если по условию задачи 9 баллов начисляются немного по другим правилам, пришли само условие задачи — тогда я подгоню алгоритм точно под него, а не только восстановлю смысл из текущего кода.

Condividi questa Q&A