Hướng dẫn giải của [VT Thiếu nhi] BÀI 23: PHANTU
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 công thức hoá học chỉ gồm H, O, N, C, mỗi nguyên tử có thể có chỉ số n (n ≤ 1000) đứng ngay sau. Tính phân tử lượng: H = 1, O = 16, N = 14, C = 12.
Sub 1: Vét cạn — ~O(tổng số nguyên tử)~
Mở rộng công thức: mỗi E_n được viết lại thành n lần E (ví dụ N2O3 thành NNOOO), rồi cộng khối lượng từng nguyên tử. Cách này trực tiếp nhưng tốn bộ nhớ khi chỉ số lớn. Đạt 10/10 test.
#include <bits/stdc++.h>
using namespace std;
int main() {
freopen("PHANTU.INP", "r", stdin);
freopen("PHANTU.OUT", "w", stdout);
ios::sync_with_stdio(false);
cin.tie(nullptr);
string s;
cin >> s;
// Vét cạn: mở rộng công thức, mỗi nguyên tử E_n được viết lại thành n lần E
string ex;
int n = s.size();
for (int i = 0; i < n; ) {
char c = s[i++];
int k = 0;
while (i < n && isdigit(s[i])) k = k * 10 + (s[i++] - '0');
if (k == 0) k = 1;
for (int t = 0; t < k; t++) ex += c;
}
// Cộng khối lượng của từng nguyên tử đã mở rộng
long long total = 0;
for (char c : ex) {
if (c == 'H') total += 1;
else if (c == 'O') total += 16;
else if (c == 'N') total += 14;
else if (c == 'C') total += 12;
}
cout << total << '\n';
return 0;
}
Sub 2: Đọc và nhân trực tiếp — ~O(độ dài xâu)~
Đọc từng nguyên tử, nếu có chỉ số k (có thể nhiều chữ số) thì cộng khối lượng × k; nếu không có chỉ số thì k = 1. Không cần mở rộng xâu. Đạt 10/10 test.
#include <bits/stdc++.h>
using namespace std;
// Khối lượng nguyên tử H, O, N, C
long long weight(char c) {
if (c == 'H') return 1;
if (c == 'O') return 16;
if (c == 'N') return 14;
if (c == 'C') return 12;
return 0;
}
int main() {
freopen("PHANTU.INP", "r", stdin);
freopen("PHANTU.OUT", "w", stdout);
ios::sync_with_stdio(false);
cin.tie(nullptr);
string s;
cin >> s;
long long total = 0;
int n = s.size();
// Đọc từng nguyên tử, nếu sau nó có số k thì nhân khối lượng với k
for (int i = 0; i < n; ) {
char c = s[i++];
long long k = 0;
while (i < n && isdigit(s[i])) k = k * 10 + (s[i++] - '0');
if (k == 0) k = 1; // không ghi số nghĩa là có 1 nguyên tử
total += weight(c) * k;
}
cout << total << '\n';
return 0;
}
Bình luận