Hướng dẫn giải của Tổng chữ số_02_04
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Lời giải này đang bị ẩn cho đến khi bạn chọn mở ra.
Chúng tôi khuyên bạn nên tự thử giải bài trước. Việc mở lời giải có thể làm lộ mất ý tưởng chính trước khi bạn có cơ hội tự giải.
Bạn phải đăng nhập để mở lời giải này.
Đăng nhậpTác giả: , , ,
Hiểu bài toán
Bài toán yêu cầu tính tổng các chữ số của một số nguyên lớn N. N được biểu diễn dưới dạng một chuỗi ký tự hoặc số nguyên lớn (không thể lưu trong kiểu dữ liệu nguyên tiêu chuẩn). Input là một số N, Output là tổng các chữ số của N. Ví dụ: N = 123, Output = 1 + 2 + 3 = 6.
Các cách tiếp cận
Cách Xử lý chuỗi trực tiếp (Direct String Processing)
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
// Mở file input/output
freopen("SUMN.INP", "r", stdin);
freopen("SUMN.OUT", "w", stdout);
string N;
cin >> N;
long long sum = 0;
for (char c : N) {
sum += (c - '0'); // chuyển ký tự sang số
}
cout << sum;
return 0;
}
- Time Complexity: O(D), với D là số lượng chữ số của N
- Space Complexity: O(D)
Đây là cách tiếp cận trực quan và được sử dụng trong các giải pháp đã cho. Ta đọc N dưới dạng chuỗi ký tự. Sau đó, duyệt qua từng ký tự trong chuỗi, trừ đi mã ASCII của ký tự '0' để thu获得 giá trị số thực tế của ký tự đó, và cộng vào biến tổng. Cuối cùng in ra tổng. Phương pháp này rất hiệu quả và dễ hiểu.
Cách Sử dụng toán tử nhập xuất (I/O Operator Approach)
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
freopen("sumn.inp", "r", stdin);
freopen("sumn.out", "w", stdout);
string N;
cin >> N;
long long sum = 0;
for (char c : N) sum += (c - '0');
cout << sum;
return 0;
}
- Time Complexity: O(D)
- Space Complexity: O(D)
Giải pháp này tương tự như cách tiếp cận đầu tiên, chỉ khác biệt nhỏ về cách khai báo thư viện và tên file. Nó sử dụng vòng lặp for-each để duyệt qua các ký tự. Logic tính toán tổng là hoàn toàn giống nhau: chuyển đổi ký tự thành số nguyên bằng cách trừ '0'.
Cách Sử dụng biến đếm và truy cập theo chỉ số (Index-based Accumulation)
#include <bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
freopen("sumn.inp","r",stdin);
freopen("sumn.out","w",stdout);
string s;
cin>>s;
int n=s.size(),res=0;
for (int i=0;i<n;i++){
res+=s[i]-'0';
}
cout<<res;
return 0;
}
- Time Complexity: O(D)
- Space Complexity: O(D)
Cách tiếp cận này sử dụng chỉ số để truy cập từng ký tự trong chuỗi. Biến 'n' lưu độ dài chuỗi, biến 'res' lưu tổng. Vòng lặp 'for' duyệt từ 0 đến n-1, lấy ký tự tại vị trí i, chuyển đổi và cộng vào tổng. Đây là cách viết thông thường trong C++ và cũng rất hiệu quả.
Phân tích độ phức tạp
| Cách tiếp cận | Time | Space | Tên |
|---|---|---|---|
| 1 | O(D), với D là số lượng chữ số của N | O(D) | Xử lý chuỗi trực tiếp (Direct String Processing) |
| 2 | O(D) | O(D) | Sử dụng toán tử nhập xuất (I/O Operator Approach) |
| 3 | O(D) | O(D) | Sử dụng biến đếm và truy cập theo chỉ số (Index-based Accumulation) |
Bài học kinh nghiệm
- Việc sử dụng chuỗi (string) để lưu trữ số lớn là bắt buộc khi số đó vượt quá giới hạn của kiểu dữ liệu nguyên (long long).
- Quy đổi ký tự sang số nguyên bằng cách trừ đi ký tự '0' (ví dụ: '5' - '0' = 5) là thao tác cơ bản và hiệu quả nhất trong xử lý số học chuỗi.
Lỗi thường gặp
- Cố gắng khai báo biến kiểu int hoặc long long để lưu N nếu N quá lớn, dẫn đến tràn số (overflow).
- Quên chuyển đổi ký tự sang số trước khi cộng (ví dụ: sum += c thay vì sum += c - '0'), dẫn đến tính toán sai kết quả do cộng mã ASCII.
Bình luận