Bài 8: Xâu ký tự (chuỗi) trong C++ và Python: char, mã ASCII, string và các bài toán xử lý xâu
Lời mở đầu
Bốn bài trước, chương trình của chúng ta chỉ làm việc với con số. Nhưng dữ liệu đời thực phần lớn là chữ: họ tên học sinh, địa chỉ email, một câu văn cần đếm từ, hay một số nguyên dài tới 1000 chữ số mà long long không chứa nổi. Kiểu dữ liệu dành cho chúng là xâu ký tự (string, hay còn gọi là chuỗi). Điều thú vị: xâu thực chất là mảng các ký tự, nên mọi kỹ năng duyệt mảng ở bài 6 đều áp dụng y nguyên. Học xong bài này là các bạn đã có đủ “đồ nghề” cơ bản; sáu bài tiếp theo (Bài 9 → Bài 14) sẽ giúp các bạn viết chương trình đủ nhanh và làm quen với đề thi thật.
cin và getline; duyệt xâu, các hàm xử lý xâu có sẵn (đối chiếu C++ với Python); các bài toán kinh điển: đếm loại ký tự, xâu đối xứng, đếm từ. Có khung chạy tay xem từng ký tự và 10 bài tập kèm gợi ý.Lộ trình bài viết, bấm vào từng phần để nhảy tới:
Phần 1Ký tự char và bảng mã ASCII
Kiểu char lưu một ký tự, viết trong cặp nháy đơn: char c = 'A';. Điều quan trọng nhất cần biết: máy tính không lưu chữ cái mà lưu một con số đại diện cho nó, theo bảng mã ASCII. Ví dụ 'A' được lưu là 65, 'a' là 97, chữ số '0' là 48. Vì vậy ký tự hoàn toàn có thể đem đi cộng, trừ, so sánh như số!
4 vùng mã ASCII cần thuộc lòng. Không cần nhớ con số cụ thể, chỉ cần nhớ chúng liên tiếp và viết '0', 'a', 'A' trong code.
Code C++ và Python
char c = 'A';
cout << (int)c << endl; // 65: ép sang int để xem mã ASCII
cout << (char)(c + 1) << endl; // B
char d = '7';
int so = d - '0'; // 7 (con số thật, đem đi tính toán được)
if(c >= 'A' && c <= 'Z') cout << "chu hoa"; // kiểm tra c là chữ hoa
char t = c - 'A' + 'a'; // đổi sang chữ thường: 'a'
c = 'A' # Python không có kiểu char, ký tự là xâu độ dài 1
print(ord(c)) # 65: ord() lấy mã ASCII
print(chr(ord(c) + 1)) # B: chr() đổi mã sang ký tự
d = '7'
so = ord(d) - ord('0') # 7 (hoặc đơn giản int(d))
if 'A' <= c <= 'Z': print("chu hoa")
t = chr(ord(c) - ord('A') + ord('a')) # 'a' (hoặc c.lower())
Ứng dụng đầu tiên rất hay gặp: tính tổng chữ số của một số khổng lồ có tới hàng nghìn chữ số. Số này không kiểu số nguyên nào chứa nổi, nên ta đọc nó như một xâu rồi đổi từng ký tự sang chữ số bằng c - '0':
Code C++ và Python
#include <iostream>
#include <string>
using namespace std;
int main(){
string s;
cin >> s;
int tong = 0;
for(int i = 0; i < s.size(); i++){
int cs = s[i] - '0';
tong += cs;
}
cout << tong;
return 0;
}
s = input().strip()
tong = 0
for c in s:
cs = ord(c) - ord('0') # hoặc int(c)
tong += cs
print(tong)
Mô phỏng trực quan. Câu "ký tự chỉ là một con số" nghe thì dễ nhưng nhiều bạn vẫn chưa thấy nó có ích gì. Em gõ một xâu không dấu rồi bấm Tiếp: mỗi ký tự hiện kèm mã ASCII, xem máy dựa vào mã để phân loại và đổi hoa – thường chỉ bằng ±32.
Phần 2Kiểu string: khai báo, nhập xâu, duyệt xâu
C++ có 2 cách lưu xâu. Cách cũ kế thừa từ ngôn ngữ C là mảng ký tự char s[100];, kết thúc bằng ký tự đặc biệt '\0'; cách này rắc rối và dễ lỗi nên ta chỉ cần biết là có. Cách hiện đại, dùng trong mọi bài thi, là kiểu string (thư viện <string>): tự co giãn độ dài, nối bằng dấu +, so sánh bằng ==, < như số.
Xâu là mảng ký tự: chỉ số từ 0 đến s.size() - 1, duyệt bằng vòng for y như mảng.
Nhập xâu có 2 cách và đây là chỗ rất nhiều bạn bị sai:
string s;
cin >> s;
// gõ: Nguyen Van An
// s = "Nguyen"
Dừng lại ở dấu cách hoặc xuống dòng đầu tiên. Dùng khi xâu chắc chắn không có dấu cách.string s;
getline(cin, s);
// gõ: Nguyen Van An
// s = "Nguyen Van An"
Đọc tới hết dòng, giữ nguyên các dấu cách. Python: s = input() luôn đọc cả dòng.cin >> n; getline(cin, s); thì s sẽ là xâu rỗng! Lý do: cin >> n đọc xong số nhưng để lại ký tự xuống dòng '\n', getline gặp ngay ký tự đó và tưởng dòng đã hết. Cách sửa: thêm cin.ignore(); (bỏ qua 1 ký tự) ngay sau cin >> n;.Ví dụ: đọc một dòng bất kỳ, đếm số chữ hoa, chữ thường, chữ số và ký tự khác (dấu cách, dấu câu…). Đây là bài kinh điển kết hợp duyệt xâu với kiểm tra vùng mã ASCII ở phần 1:
Code C++ và Python
#include <iostream>
#include <string>
using namespace std;
int main(){
string s;
getline(cin, s);
int hoa = 0, thuong = 0, so = 0, khac = 0;
for(int i = 0; i < s.size(); i++){
char c = s[i];
if(c >= 'A' && c <= 'Z') hoa++;
else if(c >= 'a' && c <= 'z') thuong++;
else if(c >= '0' && c <= '9') so++;
else khac++;
}
cout << hoa << " " << thuong << " " << so << " " << khac;
return 0;
}
s = input()
hoa = thuong = so = khac = 0
for c in s:
if 'A' <= c <= 'Z':
hoa += 1
elif 'a' <= c <= 'z':
thuong += 1
elif '0' <= c <= '9':
so += 1
else:
khac += 1
print(hoa, thuong, so, khac)
# Python có sẵn: c.isupper(), c.islower(), c.isdigit()
Một thao tác cơ bản khác: biến đổi từng ký tự của xâu. Ví dụ đảo chữ hoa thành thường, thường thành hoa, tự cài bằng phép cộng trừ mã ASCII (không dùng hàm có sẵn):
Code C++ và Python
#include <iostream>
#include <string>
using namespace std;
int main(){
string s;
cin >> s;
for(int i = 0; i < s.size(); i++){
if(s[i] >= 'a' && s[i] <= 'z')
s[i] = s[i] - 'a' + 'A';
else if(s[i] >= 'A' && s[i] <= 'Z')
s[i] = s[i] - 'A' + 'a';
}
cout << s;
return 0;
}
s = list(input().strip()) # xâu Python không sửa được từng ký tự → đổi sang list
for i in range(len(s)):
if 'a' <= s[i] <= 'z':
s[i] = chr(ord(s[i]) - ord('a') + ord('A'))
elif 'A' <= s[i] <= 'Z':
s[i] = chr(ord(s[i]) - ord('A') + ord('a'))
print("".join(s))
# Cách ngắn: print(input().swapcase())
s[i] = 'A' (báo lỗi TypeError). Muốn sửa từng ký tự thì đổi sang list: a = list(s), sửa xong ghép lại s = "".join(a); hoặc tạo xâu mới bằng phép cộng. Còn string của C++ thì sửa thoải mái.Phần 3Các hàm xử lý xâu có sẵn (C++ và Python)
Tự cài thủ công giúp hiểu bản chất, nhưng khi làm bài ta tận dụng các hàm có sẵn cho nhanh. Bảng dưới đây ví dụ với s = "lap trinh". Chú ý: trong C++, substr nhận vị trí bắt đầu và độ dài, còn lát cắt Python s[a:b] nhận vị trí bắt đầu và vị trí kết thúc (không lấy $b$).
| Việc cần làm | C++ (string) | Python (str) | Kết quả |
|---|---|---|---|
| Độ dài | s.size() | len(s) | 9 |
| Nối xâu | s + "!" | s + "!" | "lap trinh!" |
| Lấy xâu con | s.substr(4, 3) | s[4:7] | "tri" |
| Tìm xâu con | s.find("trinh") | s.find("trinh") | 4 |
| Không tìm thấy | s.find("x") == string::npos | s.find("x") == -1 | true |
| Chèn | s.insert(3, "!") | s[:3] + "!" + s[3:] | "lap! trinh" |
| Xóa | s.erase(0, 4) | s[4:] | "trinh" |
| Thay thế | s.replace(0, 3, "hoc") | s.replace("lap", "hoc") | "hoc trinh" |
| Đảo ngược | reverse(s.begin(), s.end()) | s[::-1] | "hnirt pal" |
| Số → xâu | to_string(123) | str(123) | "123" |
| Xâu → số | stoi("123"), stoll(...) | int("123") | 123 |
| So sánh từ điển | "abc" < "abd" | "abc" < "abd" | true |
Lưu ý s.insert, s.erase, s.replace của C++ sửa trực tiếp xâu s; còn Python luôn tạo ra xâu mới (vì xâu Python bất biến), muốn giữ kết quả phải gán lại s = s.replace(...). Chạy thử đoạn code tổng hợp sau và đối chiếu với bảng:
Code C++ và Python
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main(){
string s = "lap trinh";
cout << s.size() << endl; // 9
cout << s.substr(4, 3) << endl; // tri
cout << s.find("trinh") << endl; // 4
if(s.find("x") == string::npos) cout << "khong co x" << endl;
s.insert(3, "!"); // s = "lap! trinh"
s.erase(3, 1); // xoá 1 ký tự tại vị trí 3: "lap trinh"
s.replace(0, 3, "hoc"); // s = "hoc trinh"
cout << s << endl;
string t = s;
reverse(t.begin(), t.end()); // t = "hnirt coh"
sort(t.begin(), t.end()); // sắp xếp các ký tự: " choihnrt"
int x = stoi("2026") + 1; // 2027
cout << to_string(x) + "!" << endl; // 2027!
return 0;
}
s = "lap trinh"
print(len(s)) # 9
print(s[4:7]) # tri
print(s.find("trinh")) # 4
if s.find("x") == -1: print("khong co x")
s = s[:3] + "!" + s[3:] # "lap! trinh"
s = s[:3] + s[4:] # "lap trinh"
s = s.replace("lap", "hoc") # "hoc trinh"
print(s)
t = s[::-1] # "hnirt coh"
t = "".join(sorted(t)) # " choihnrt"
x = int("2026") + 1 # 2027
print(str(x) + "!") # 2027!
# Python còn: s.split(), " ".join(...), s.upper(), s.lower(), s.count("a")
string của C++ thực chất lưu từng byte. Chữ có dấu như "ă", "ệ" trong bảng mã UTF-8 chiếm 2 – 3 byte, nên s.size() của "Việt" là 6 chứ không phải 4, và s[1] chỉ là một mảnh của chữ "i". Vì thế đề thi tin học hầu như luôn cho xâu không dấu. Python 3 thì xử lý được chữ có dấu đúng như mong đợi: len("Việt") == 4.Phần 4Bài toán kinh điển: xâu đối xứng, đếm từ
Xâu đối xứng (palindrome) là xâu đọc xuôi hay ngược đều giống nhau: "level", "abba", "racecar". Cách kiểm tra đẹp nhất là dùng hai con trỏ: $l$ ở đầu xâu, $r$ ở cuối xâu, so sánh $s[l]$ với $s[r]$ rồi cùng tiến vào giữa. Chỉ cần một cặp khác nhau là kết luận không đối xứng.
Code C++ và Python
#include <iostream>
#include <string>
using namespace std;
bool doiXung(string s){
int l = 0, r = s.size() - 1;
while(l < r){
if(s[l] != s[r]) return false;
l++; r--;
}
return true;
}
int main(){
string s;
cin >> s;
if(doiXung(s)) cout << "YES";
else cout << "NO";
return 0;
}
def doi_xung(s):
l, r = 0, len(s) - 1
while l < r:
if s[l] != s[r]:
return False
l += 1
r -= 1
return True
s = input().strip()
print("YES" if doi_xung(s) else "NO")
# Cách ngắn: print("YES" if s == s[::-1] else "NO")
Đếm số từ trong một câu, câu có thể có nhiều dấu cách liền nhau hoặc dấu cách ở đầu, cuối. Mẹo: một từ mới bắt đầu tại vị trí $i$ khi $s[i]$ không phải dấu cách và (hoặc $i = 0$, hoặc $s[i-1]$ là dấu cách). Đếm số vị trí bắt đầu là ra số từ, không cần tách từ ra.
Code C++ và Python
#include <iostream>
#include <string>
using namespace std;
int main(){
string s;
getline(cin, s);
int dem = 0;
for(int i = 0; i < s.size(); i++){
if(s[i] != ' ' && (i == 0 || s[i - 1] == ' '))
dem++;
}
cout << dem;
return 0;
}
s = input()
dem = 0
for i in range(len(s)):
if s[i] != ' ' and (i == 0 or s[i - 1] == ' '):
dem += 1
print(dem)
# Cách ngắn: print(len(s.split())) (split() tự bỏ mọi dấu cách thừa)
#include <sstream> rồi stringstream ss(s); string w; while(ss >> w) { ... }, mỗi vòng w là một từ, mọi dấu cách thừa tự bị bỏ qua. Python tương ứng là for w in s.split():.Mô phỏng trực quan. Đọc code hai con trỏ rồi mà vẫn khó hình dung i, j chạy thế nào? Em bấm Tiếp để xem hai con trỏ đi từ hai đầu vào giữa, thử cả xâu độ dài chẵn, lẻ và một xâu không đối xứng để thấy vòng lặp dừng sớm ra sao.
Đếm từ cũng là chỗ rất hay sai khi xâu có dấu cách thừa. Em xem máy nhận ra "chỗ bắt đầu một từ" như thế nào, rồi tự gõ thêm dấu cách ở đầu, ở cuối, ở giữa để thử:
Bài tậpLuyện xử lý xâu
Nếu không nói gì thêm, xâu chỉ gồm chữ cái tiếng Anh không dấu, chữ số và dấu cách, độ dài không quá $10^5$. Bài nào đọc cả dòng thì nhớ dùng getline.
Đọc một dòng, đếm số nguyên âm (a, e, i, o, u, kể cả chữ hoa).
Hoc Lap Trinh Cung Thay5💡 Gợi ý
tolower(c) hoặc cộng 32 như phần 2) rồi so với 5 nguyên âm. Có thể dùng string("aeiou").find(c) != string::npos cho gọn.Xem code tham khảo (C++ / Python)
#include <iostream>
#include <string>
using namespace std;
int main(){
string s;
getline(cin, s);
int dem = 0;
for(char c : s){
c = tolower(c);
if(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') dem++;
}
cout << dem;
return 0;
}
s = input()
print(sum(1 for c in s.lower() if c in "aeiou"))
Đọc một dòng, in xâu theo thứ tự ngược lại. Yêu cầu tự đảo bằng vòng lặp (không dùng reverse).
tin hoc 1001 coh nit💡 Gợi ý
s[i] với s[n - 1 - i] cho $i$ từ 0 tới $n/2 - 1$. Hoặc đơn giản in ra từ cuối về đầu.Xem code tham khảo (C++ / Python)
#include <iostream>
#include <string>
using namespace std;
int main(){
string s;
getline(cin, s);
int n = s.size();
for(int i = 0; i < n / 2; i++){
char t = s[i];
s[i] = s[n - 1 - i];
s[n - 1 - i] = t;
}
cout << s;
return 0;
}
s = input()
print(s[::-1])
Xâu gồm chữ cái và chữ số lẫn lộn (không có dấu cách). Tính tổng các chữ số xuất hiện trong xâu.
a1b22c33314💡 Gợi ý
'0' tới '9' thì cộng c - '0' vào tổng. Nâng cao: tính tổng các số (a1b22c333 → 1 + 22 + 333 = 356) bằng cách ghép dần so = so * 10 + (c - '0'), gặp chữ cái thì cộng so vào tổng rồi đặt lại bằng 0.Xem code tham khảo (C++ / Python)
#include <iostream>
#include <string>
using namespace std;
int main(){
string s;
cin >> s;
int tong = 0;
for(char c : s){
if(c >= '0' && c <= '9') tong += c - '0';
}
cout << tong;
return 0;
}
s = input().strip()
print(sum(int(c) for c in s if c.isdigit()))
Đọc một dòng là họ tên viết lộn xộn: thừa dấu cách ở đầu, cuối, giữa các từ, chữ hoa thường lẫn lộn. In họ tên đã chuẩn hoá: các từ cách nhau đúng 1 dấu cách, chữ cái đầu mỗi từ viết hoa, các chữ còn lại viết thường.
nGUYEN vAN an Nguyen Van An💡 Gợi ý
stringstream (mẹo ở phần 4). Với mỗi từ w: w[0] = toupper(w[0]), các ký tự còn lại tolower. Ghép các từ, giữa 2 từ thêm đúng một dấu cách. Đây là bài "đặc sản" của các đề thi tin học trẻ, HSG cấp huyện.Xem code tham khảo (C++ / Python)
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main(){
string s, w, kq = "";
getline(cin, s);
stringstream ss(s);
while(ss >> w){
w[0] = toupper(w[0]);
for(int i = 1; i < w.size(); i++) w[i] = tolower(w[i]);
if(kq != "") kq += " ";
kq += w;
}
cout << kq;
return 0;
}
s = input()
print(" ".join(w[0].upper() + w[1:].lower() for w in s.split()))
Đọc một dòng. Với mỗi chữ cái (không phân biệt hoa thường) có xuất hiện, in ra chữ cái đó (viết thường) và số lần xuất hiện, theo thứ tự a → z.
Hello Worldd 1
e 1
h 1
l 3
o 2
r 1
w 1💡 Gợi ý
c (đã đổi về thường) ứng với ô dem[c - 'a']. Cuối cùng duyệt k từ 0 tới 25, ô nào khác 0 thì in (char)('a' + k) và dem[k].Xem code tham khảo (C++ / Python)
#include <iostream>
#include <string>
using namespace std;
int dem[26];
int main(){
string s;
getline(cin, s);
for(char c : s){
c = tolower(c);
if(c >= 'a' && c <= 'z') dem[c - 'a']++;
}
for(int k = 0; k < 26; k++){
if(dem[k] > 0) cout << (char)('a' + k) << " " << dem[k] << endl;
}
return 0;
}
s = input().lower()
dem = [0] * 26
for c in s:
if 'a' <= c <= 'z':
dem[ord(c) - ord('a')] += 1
for k in range(26):
if dem[k] > 0:
print(chr(ord('a') + k), dem[k])
Đọc một câu, in ra từ dài nhất (nếu nhiều từ cùng độ dài lớn nhất thì in từ xuất hiện đầu tiên) và độ dài của nó.
toi thich hoc lap trinh thuat toanthich 5💡 Gợi ý
stringstream, giữ biến best; từ nào có w.size() > best.size() thì cập nhật (dấu > để giữ từ đầu tiên khi bằng nhau). Chính là bài tìm max ở bài 6, chỉ khác là so sánh độ dài.Xem code tham khảo (C++ / Python)
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main(){
string s, w, best = "";
getline(cin, s);
stringstream ss(s);
while(ss >> w){
if(w.size() > best.size()) best = w;
}
cout << best << " " << best.size();
return 0;
}
s = input()
best = ""
for w in s.split():
if len(w) > len(best):
best = w
print(best, len(best))
Xâu chỉ gồm chữ thường. Nén xâu bằng cách thay mỗi đoạn ký tự giống nhau liên tiếp bằng ký tự đó kèm số lần lặp.
aaabccdddda3b1c2d4💡 Gợi ý
dem. Nếu s[i] == s[i - 1] thì dem++, ngược lại in ký tự trước cùng dem rồi đặt lại dem = 1. Đừng quên in đoạn cuối cùng sau vòng lặp! Ghép số vào xâu dùng to_string(dem).Xem code tham khảo (C++ / Python)
#include <iostream>
#include <string>
using namespace std;
int main(){
string s, kq = "";
cin >> s;
int dem = 1;
for(int i = 1; i <= s.size(); i++){
if(i < s.size() && s[i] == s[i - 1]) dem++;
else{
kq += s[i - 1] + to_string(dem);
dem = 1;
}
}
cout << kq;
return 0;
}
s = input().strip()
kq, dem = "", 1
for i in range(1, len(s) + 1):
if i < len(s) and s[i] == s[i - 1]:
dem += 1
else:
kq += s[i - 1] + str(dem)
dem = 1
print(kq)
Hai xâu gọi là đảo chữ (anagram) của nhau nếu sắp xếp lại các ký tự của xâu này thì được xâu kia (ví dụ listen và silent). Nhập 2 xâu chữ thường, in YES hoặc NO.
listen silentYES💡 Gợi ý
sort(s.begin(), s.end())) rồi so sánh bằng ==, độ phức tạp $O(n \log n)$. Cách 2 nhanh hơn: mảng đếm 26 ô, xâu thứ nhất cộng vào, xâu thứ hai trừ ra, cuối cùng mọi ô bằng 0 thì là đảo chữ, $O(n)$.Xem code tham khảo (C++ / Python)
#include <iostream>
#include <string>
using namespace std;
int dem[26];
int main(){
string s, t;
cin >> s >> t;
for(char c : s) dem[c - 'a']++;
for(char c : t) dem[c - 'a']--;
bool ok = true;
for(int k = 0; k < 26; k++)
if(dem[k] != 0) ok = false;
cout << (ok ? "YES" : "NO");
return 0;
}
s, t = input().split()
print("YES" if sorted(s) == sorted(t) else "NO")
Dòng 1 là xâu $s$, dòng 2 là xâu $t$ (không chứa dấu cách, $|t| \le |s| \le 1000$). Đếm số lần $t$ xuất hiện trong $s$ (các lần xuất hiện được phép chồng lên nhau).
aaaa
aa3💡 Gợi ý
s.substr(i, t.size()) == t. Hoặc dùng find trong vòng lặp: pos = s.find(t, pos + 1) cho tới khi gặp npos. Chú ý: s.count(t) của Python đếm các lần không chồng nhau ("aaaa".count("aa") = 2), nên không dùng được cho bài này.Xem code tham khảo (C++ / Python)
#include <iostream>
#include <string>
using namespace std;
int main(){
string s, t;
cin >> s >> t;
int dem = 0;
for(int i = 0; i + t.size() <= s.size(); i++){
if(s.substr(i, t.size()) == t) dem++;
}
cout << dem;
return 0;
}
s = input().strip()
t = input().strip()
print(sum(1 for i in range(len(s) - len(t) + 1) if s[i:i + len(t)] == t))
Nhập 2 số nguyên không âm $a, b$, mỗi số có tới 1000 chữ số. In ra $a + b$.
99999999999999999999 1100000000000000000000💡 Gợi ý
nho, chữ số kết quả là tong % 10, nhớ sang cột sau tong / 10. Đầu ngắn hơn coi như chữ số 0. Kết quả thu được bị ngược, nhớ đảo lại. Python có số nguyên vô hạn nên chỉ cần print(a + b), nhưng hãy thử tự cài để luyện tư duy. Đây là nền móng của chủ đề Số lớn.Xem code tham khảo (C++ / Python)
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
string cong(string a, string b){
string kq = "";
int i = a.size() - 1, j = b.size() - 1, nho = 0;
while(i >= 0 || j >= 0 || nho > 0){
int x = (i >= 0) ? a[i] - '0' : 0;
int y = (j >= 0) ? b[j] - '0' : 0;
int tong = x + y + nho;
kq += (char)('0' + tong % 10);
nho = tong / 10;
i--; j--;
}
reverse(kq.begin(), kq.end());
return kq;
}
int main(){
string a, b;
cin >> a >> b;
cout << cong(a, b);
return 0;
}
def cong(a, b):
kq = []
i, j, nho = len(a) - 1, len(b) - 1, 0
while i >= 0 or j >= 0 or nho > 0:
x = int(a[i]) if i >= 0 else 0
y = int(b[j]) if j >= 0 else 0
tong = x + y + nho
kq.append(str(tong % 10))
nho = tong // 10
i -= 1
j -= 1
return "".join(reversed(kq))
a, b = input().split()
print(cong(a, b)) # hoặc đơn giản: print(int(a) + int(b))
Học tiếp gì sau bài xâu ký tự?
Chúc mừng các bạn đã đi hết 8 bài đầu của series! Với các viên gạch: nhập xuất, rẽ nhánh, vòng lặp, hàm, mảng 1 chiều, mảng 2 chiều và xâu, các bạn đã viết được phần lớn chương trình cơ bản. Sáu bài tiếp theo giúp các bạn đi từ “viết được” sang “viết đủ nhanh để được AC”: độ phức tạp và cách bài được chấm → struct và sắp xếp nhiều tiêu chí → STL cơ bản → số học → mảng đánh dấu, cộng dồn → tổng ôn và đề thi thử. Học xong Bài 14, các bạn đi tiếp theo lộ trình học thuật toán.
- Không biết học gì trước, học gì sau, học lan man nên kiến thức bị hổng.
- Bí bài không ai gỡ, ngồi cả buổi vẫn không ra rồi bỏ cuộc.
- Code chạy được nhưng không đủ điểm, không biết sai ở đâu, chậm ở đâu.
- Không có đề thi thử và người chấm, nên không biết mình đang ở mức nào.
- Dễ nản giữa chừng khi không có ai theo sát.
- Lộ trình 111 buổi video sắp sẵn từ dòng code đầu tiên đến đề HSG thật của các tỉnh.
- Thầy trực tiếp gỡ bí, chữa bài cho từng em qua nhóm Zalo riêng.
- Hệ thống chấm bài tự động 24/7 và thi thử HSG hằng tuần để biết chính xác mình đang ở đâu.
- Đóng học phí một lần, thầy kèm lâu dài: từ thi chuyên Tin đến HSG quốc gia và cả khi lên đại học.

Nhận xét
Đăng nhận xét