Hướng dẫn giải của [VT Thiếu nhi] BÀI 30: TINH2
Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
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.
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.
Hướng dẫn giải
Cho biểu thức chỉ gồm các số nguyên, phép cộng (+), phép trừ (-) và khoảng trắng, độ dài tối đa 1000. Tính giá trị biểu thức, kết quả nằm trong kiểu long long.
Ví dụ: "12 + 18 - 16" có kết quả 14.
Sub 1: Vét cạn — ~O(n)~
Tách biểu thức thành các token rồi tính lần lượt từ trái sang phải: số đầu tiên là kết quả ban đầu, sau đó mỗi cặp (toán tử, số) được cộng hoặc trừ vào kết quả. Đạt 20/20 test.
#include <bits/stdc++.h>
using namespace std;
int main() {
freopen("TINH2.INP", "r", stdin);
freopen("TINH2.OUT", "w", stdout);
ios::sync_with_stdio(false);
cin.tie(nullptr);
// Vét cạn: tách thành token, biểu thức có dạng số (toán tử số)*
vector<string> tok;
string t;
while (cin >> t) tok.push_back(t);
long long res = stoll(tok[0]);
for (size_t i = 1; i + 1 < tok.size(); i += 2) {
string op = tok[i];
long long v = stoll(tok[i + 1]);
if (op == "+") res += v;
else res -= v;
}
cout << res << '\n';
return 0;
}
Sub 2: Duyệt từng ký tự và xử lý dấu — ~O(n)~
Duyệt từng ký tự, bỏ qua khoảng trắng. Cần phân biệt dấu '-' là phép trừ (đứng sau một số) hay dấu của số (đứng ở đầu biểu thức hoặc sau toán tử). Biến expectNum cho biết đang chờ một số hay vừa đọc xong một số. Mỗi số ghép nhiều chữ số, rồi cộng dấu phép toán × dấu số × giá trị. Đạt 20/20 test.
#include <bits/stdc++.h>
using namespace std;
int main() {
freopen("TINH2.INP", "r", stdin);
freopen("TINH2.OUT", "w", stdout);
ios::sync_with_stdio(false);
cin.tie(nullptr);
string s, line;
while (getline(cin, line)) s += line;
// Đọc từng số nguyên (có thể âm), dấu '+'/'-' ở giữa là phép toán
long long res = 0;
int sign = 1; // dấu của số đang chờ cộng vào kết quả
bool expectNum = true; // đang ở vị trí phải có một số (đầu biểu thức hoặc sau toán tử)
int n = s.size();
for (int i = 0; i < n; ) {
char c = s[i];
if (c == ' ' || c == '\r' || c == '\t') { i++; continue; }
if (c == '+' && !expectNum) { sign = 1; expectNum = true; i++; continue; }
if (c == '-' && !expectNum) { sign = -1; expectNum = true; i++; continue; }
// Gặp số: ghép các chữ số, dấu '-' ở đầu số nếu có
int numSign = 1;
if (c == '-' || c == '+') { numSign = (c == '-') ? -1 : 1; i++; }
long long v = 0;
while (i < n && isdigit(s[i])) v = v * 10 + (s[i++] - '0');
res += sign * numSign * v;
sign = 1;
expectNum = false;
}
cout << res << '\n';
return 0;
}
Bình luận