# SES4 :::::spoiler EXPERTS SYSTEMS ::::warning **Ý tưởng:** - Bài khó - Duyệt từng số từ 1 đến *n* - Với mỗi i từ *1* đến *n*, tìm phần không chính phương. - Sử dụng map để lưu phần không chính phương và đếm có bao nhiêu số có cùng phần không chính phương. - Sau khi đếm xong, duyệt qua các kết quả đếm. Với mỗi nhóm có số lượng là *c*, cộng thêm *c* * (*c* - 1) / 2 vào tổng kết quả. - Mọi số nguyên dương *x* đều có thể được phân tích duy nhất dưới dạng *x* = *s* * *k*^2, trong đó *s* là một số không chia hết cho bất kỳ số chính phương nào lớn hơn 1. Số *s* này được gọi là phần không chính phương của x. - Ví dụ: - 12 = 3 * 4 = 3 * 2^2. Phần không chính phương của 12 là 3. - 18 = 2 * 9 = 2 * 3^2. Phần không chính phương của 18 là 2. - 8 = 2 * 4 = 2 * 2^2. Phần không chính phương của 8 là 2. - 9 = 1 * 9 = 1 * 3^2. Phần không chính phương của 9 là 1. **Ví dụ:** | Input | Output | | --------------- | --------------- | | 1 | 0 | | 5 | 1 | | 10 | 4 | | 25 | 16 | | 100000000000000 | 936751578020184 | :::: ::::danger **Code:** :::spoiler C++ ```cpp= #include <iostream> #include <map> using namespace std; int getSquareFreePart(int n) { for (int i = 2; i * i <= n; ++i) { while (n % (i * i) == 0) { n /= (i * i); } } return n; } int main() { ifstream input("EXPERTSSYSTEMS.INP"); ofstream output("EXPERTSSYSTEMS.OUT"); int n; input >> n; if (n == 1) { cout << 0; return 0; } std::map<int, int> counts; for (int i = 1; i <= n; ++i) { int sqFreePart = getSquareFreePart(i); counts[sqFreePart]++; } long long totalPairs = 0; for (auto entry : counts) { long long c = entry.second; if (c > 1) { totalPairs += c * (c - 1) / 2; } } output << totalPairs % 977555333311111LL << std::endl; input.close(); output.close(); return 0; } ``` ::: :::: ::::success > Personal Comment: Code chạy chậm (image) :::: ::::: :::::spoiler XENOGENESIS ::::warning **Ý tưởng:** - Tạo một mảng phụ *prefix_sum* có kích thước *n*+1 để lưu lại tổng từ 1 đến i của chỉ số, như vậy sẽ tối ưu cho việc các việc sau vì việc tạo mảng chỉ có O(N). - Giờ thì ta tính tổng [*l*, *r*] bằng prefix_sum[*r*] - prefix_sum[*l* - 1] là được lets go. **Ví dụ:** | Input | Output | | --------------------------------------------------------------------- | ------------------------------------------------- | | 5 5 5<br>1 5 10 25 100000000000000<br>1 1<br>1 2<br>1 3<br>1 4<br>1 5 | SUCKDAY<br>SUNDAY<br>SUNDAY<br>SUNDAY<br>SUNDAY | | 5 5 5<br>0 1 4 16 936751578020184<br>1 1<br>1 2<br>1 3<br>1 4<br>1 5 | SUCKDAY<br>SUCKDAY<br>SUCKDAY<br>SUNDAY<br>SUNDAY | :::: ::::danger **Code:** :::spoiler C++ ```cpp= #include <iostream> #include <vector> #include <numeric> using namespace std; int main() { ifstream input("XENOGENESIS.INP"); ofstream output("XENOGENESIS.OUT"); long long n, x; int q; input >> n >> x >> q; vector<long long> a(n + 1); for (int i = 1; i <= n; ++i) { input >> a[i]; } vector<long long> prefixSum(n + 1, 0); for (int i = 1; i <= n; ++i) { prefixSum[i] = prefixSum[i - 1] + a[i]; } for (int k = 0; k < q; ++k) { int l, r; input >> l >> r; long long currentSum = prefixSum[r] - prefixSum[l - 1]; if (currentSum > x) { output << "SUNDAY\n"; } else { output << "SUCKDAY\n"; } } input.close(); output.close(); return 0; } ``` ::: :::: ::::success > Personal Comment: (image) :::: ::::: :::::spoiler ANAGRAMMATIZATION ::::warning **Ý tưởng:** - Tạo một mãng *counts* với kích thước *n*+1 - Với mỗi (*l*, *r*), ta counts[*l*]++ và counts[*r*+1]-- - Sau đó duyệt qua mảng *count* để tính tổng: counts[i] = counts[i-1] + counts[i] - Sắp xếp lại mảng *a* (mảng chứa các số input cho) và mảng *count* theo thứ tự giảm dần - Tạo một biến để lưu *maxS* - Duyệt qua 2 mảng trên, cứ mỗi *i*: - Cộng (a[i] * counts[i]) vào maxS - Kết quả mod 97755533311111 rồi in ra **Ví dụ:** | Input | Output | | ------------------------------------------------------------------- | --------------- | | 5 5<br>1 5 10 25 100000000000000<br>1 1<br>1 2<br>1 3<br>1 4<br>1 5 | 500000000000141 | | 5 5<br>0 1 4 16 936751578020184<br>1 1<br>1 2<br>1 3<br>1 4<br>1 5 | 773536556856554 | | 6 6<br>1 2 3 1 2 3<br>1 2<br2 3<br>1 3<br>2 4<br>3 4<br>1 4 | 42 | :::: ::::danger **Code:** :::spoiler C++ ```cpp= //No code ``` ::: :::: ::::success > Personal Comment: (image) :::: ::::: :::::spoiler MASS TELEPORTATION ::::warning **Ý tưởng:** - Ta thấy hàm teleport(*S*) được đề bài cho có nhiệm vụ là rotate số cuối lên đầu, sau một lúc rotate thì số sẽ trở về số cũ *S* - Vậy thì cứ xài hàm tele rồi update một biến *max* là ta tìm được số lớn nhất - Lập lại *n* chữ số (số chữ số trong tele ID) là được vì thế nào cũng rotate lại về số gốc mà **Ví dụ:** | Input | Output | | ------------------------- | ------------------------- | | 42069 | 94206 | | 1234567890 | 1234567890 | | 12345678987654321 | 98765432112345678 | | 1999999999999999999999991 | 9999999999999999999999911 | :::: ::::danger **Code:** :::spoiler C++ ```cpp= //No code ``` ::: :::: ::::success > Personal Comment: (image) :::: ::::: ## BTVN: ### 28/06/2025: A - R (Req3): :::::spoiler A - R ::::warning > Anh đọc xong r e chuyển qua SES3 ::::danger **A - R:** :::spoiler A ```cpp= #include <iostream> using namespace std; int main() { int x; cin >> x; return 0; } ``` ::: :::spoiler B ```cpp= #include <iostream> using namespace std; int main() { int x; cin >> x; cout << x; return 0; } ``` ::: :::spoiler C ```cpp= #include <iostream> using namespace std; int main() { int x, y; cin >> x >> y; cout << x << endl << y; return 0; } ``` ::: :::spoiler D endl dễ debug hơn \n, \n nhanh hơn endl ::: :::spoiler E, F cerr dùng để in ra error, để debug, judge không quan tâm cout dùng cũng dùng để in, judge chấm đáp án bằng thứ in ra của cout ::: :::spoiler G ```cpp= #include <iostream> using namespace std; int main() { int x, y; cin >> x >> y; if (x != y) cout << ((x > y) ? "GREATER" : "LESS"); else cout << "EQUAL"; return 0; } ``` ::: :::spoiler H ```cpp= #include <iostream> using namespace std; int main() { int x, y, z; cin >> x >> y >> z; if (x >= y && x >= z) cout << x; else if (y >= x && y >= z) cout << y; else cout << z; return 0; } ``` ::: :::spoiler I ```cpp= #include <iostream> using namespace std; int main() { int x, y, z; cin >> x >> y >> z; if (x <= y && x <= z) cout << x; else if (y <= x && y <= z) cout << y; else cout << z; return 0; } ``` ::: :::spoiler J ```cpp= #include <iostream> using namespace std; int main() { int x, y, z; cin >> x >> y >> z; if ((x >= y && x <= z) || (x <= y && x >= z)) cout << x; else if ((y >= x && y <= z) || (y <= x && y >= z)) cout << y; else cout << z; return 0; } ``` ::: :::spoiler K ```cpp= #include <iostream> using namespace std; int main() { int x, result; cin >> result >> x; if (x > result) result = x; cin >> x; if (x > result) result = x; cin >> x; if (x > result) result = x; cin >> x; if (x > result) result = x; cout << result; return 0; } ``` ::: :::spoiler L ```cpp= #include <iostream> using namespace std; int main() { int x, seGr, gr; cin >> seGr >> gr; if (seGr > gr) swap(seGr, gr); cin >> x; if (x > gr) { seGr = gr; gr = x; } else if (x > seGr) seGr = x; cin >> x; if (x > gr) { seGr = gr; gr = x; } else if (x > seGr) seGr = x; cin >> x; if (x > gr) { seGr = gr; gr = x; } else if (x > seGr) seGr = x; cout << seGr; return 0; } ``` ::: :::spoiler M ```cpp= #include <iostream> using namespace std; int main() { int x, gr, n = 4999; cin >> gr; while (n) cin >> x; if (x > gr) { gr = x; } n--; } cout << gr; return 0; } ``` ::: :::spoiler N ```cpp= #include <iostream> using namespace std; int main() { int x, seGr, gr, n = 4998; cin >> seGr >> gr; if (seGr > gr) swap(seGr, gr); while (n) cin >> x; if (x > gr) { seGr = gr; gr = x; } else if (x > seGr) seGr = x; n--; } cout << seGr; return 0; } ``` ::: :::spoiler O, P ```cpp= #include <iostream> using namespace std; int main() { int x, gr, n; cin >> gr; while (n) cin >> x; if (x > gr) { gr = x; } n--; } cout << gr; return 0; } ``` ::: :::spoiler Q ```cpp= #include <iostream> using namespace std; int main() { int x, seGr, gr, n; cin >> n >> seGr >> gr; if (seGr > gr) swap(seGr, gr); while (n - 2) cin >> x; if (x > gr) { seGr = gr; gr = x; } else if (x > seGr) seGr = x; n--; } cout << seGr; return 0; } ``` ::: :::spoiler R ```cpp= #include <iostream> using namespace std; int main() { int x, n, total = 0; cin >> n; while (n) cin >> x; total += x; n--; } cout << total; return 0; } ``` ::: :::: ::::: 12 bài 800 (Req3): :::::spoiler Codeforces 22A - Second Order Statistics ::::info **Link:** [22A_CF](https://codeforces.com/contest/22/problem/A) **ELO:** 800 **Tags:** brute force :::: ::::warning **Tóm tắt:** - Cho *n* số nguyên, xem số bé nhì (lớn hơn số bé nhất) là số nào. - Nếu không tìm thấy số bé nhì, in ra "NO" **Ví dụ:** | Input | Output | | -------------- | ------ | | 4<br>1 2 2 -4 | 1 | | 5<br>1 2 3 1 1 | 2 | :::: ::::danger **Code (+ Giải thích):** :::spoiler C++ ```cpp= #include <iostream> #include <algorithm> #include <vector> using namespace std; int main() { int n; cin >> n; // Nhập vào n (bao nhiêu số nguyên) vector<int> num(n); // Mảng chứa các số nguyên for (int i = 0; i < n; i++) { // Nhập vào từng số nguyên cin >> num[i]; } sort(num.begin(), num.end()); // Dùng hàm sort() để sắp xếp các phần từ trong mảng từ bé đến lớn for (int i = 0; i < n; i++) { // Duyệt qua từng số nguyên if (num[i] > num[0]) { // Nếu số đang duyệt lớn hơn số bé nhất (biết là số bé nhất vì sắp xếp rồi) cout << num[i]; // In ra số bé nhì break; // Dừng duyệt } else if (i == n - 1) { // Không tìm thấy số bé nhì cout << "NO"; // In ra "NO" break; // Dừng duyệt } } return 0; } ``` ::: :::: ::::success > Personal Comment: Đề bài bị complicated hóa :v ![image](https://hackmd.io/_uploads/SJTOJ1pVxx.png) :::: ::::: :::::spoiler Codeforces 49A - Sleuth ::::info **Link:** [49A_CF](https://codeforces.com/contest/49/problem/A) **ELO:** 800 **Tags:** implementation **Number requested by:** Gia Tuấn | Mokibam (GOT /2) :::: ::::warning **Tóm tắt:** - Cho một chuỗi, kiểm tra chữ cái cuối cùng của chuỗi có phải là nguyên âm (A, E, I, O, U, Y) không. - Chữ cái đó phải có ở trong bảng chữ cái (A - Z). **Ví dụ:** | Input | Output | | ----------------------------------------------------------- | ------ | | Is it a melon? | NO | | Is it an apple? | YES | | ㅤㅤIsㅤㅤㅤㅤㅤit a banana ? | YES | | Isㅤㅤㅤit an appleㅤㅤand aㅤㅤbananaㅤㅤㅤsimultaneouSLY? | YES | :::: ::::danger **Code (+ Giải thích):** :::spoiler C++ ```cpp= #include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { string ques; getline(cin, ques); // Dùng getline để nhận cả một dòng input thành 1 chuỗi char lastC = ' '; // Lưu từ cuối cùng của câu hỏi vector<char> vowels = {'a', 'e', 'i', 'o', 'u', 'y'}; // Các nguyên âm // Duyệt ngược từ cuối đến đầu chuỗi for (int i = ques.length() - 2; i >= 0; i--) { // ques.length -1 luôn là dấu ? hoặc không có gì, nhưng kiểm tra từ ques.length() - 2 vẫn tối ưu hơn if (isalpha(ques[i])) { // Nếu từ đang duyệt là 1 chữ cái (A - Z) lastC = towlower(ques[i]); // Lưu vào lastC từ đó dưới dạng in thường break; // Dừng duyệt } } if (find(vowels.begin(), vowels.end(), lastC) != vowels.end()) cout << "YES" << endl; // Nếu từ cuối đó là một nguyên âm in ra "YES" else cout << "NO" << endl; // Ngược lại in ra "NO" return 0; } ``` ::: :::: ::::success > Personal Comment: Easy one ngl. ![image](https://hackmd.io/_uploads/SJm7gSpEgl.png) :::: ::::: :::::spoiler Codeforces 50A - Domino piling ::::info **Link:** [50A_CF](https://codeforces.com/problemset/problem/50/A) **ELO:** 800 **Tags:** greedy, math :::: ::::warning **Tóm tắt:** - Cho một hình chữ nhật có kích thước *m* * *n* - Ta có thể đặt bao nhiêu hình chữ nhật có kích thước 2 x 1 cũng được để lấp đầy hình chữ nhật trên - Các quy tắc: - 2 hình chữ nhật không được đặt đè lên nhau - 1 hình chữ nhật lắp đầy 2 ô trong hình chữ nhật lớn - Các hình chữ nhật chỉ được đặt trong hình chữ nhật lớn, được phép đụng cạnh của hình chữ nhật lớn **Ví dụ:** | Input | Output | | ----- | ------ | | 2 4 | 4 | | 3 3 | 4 | :::: ::::danger **Code (+ Giải thích):** :::spoiler C++ ```cpp= #include <iostream> using namespace std; int main() { int m, n; cin >> m >> n; // Nhập vào m và n cout << m * n / 2 << endl; // Đáp án sẽ là diện tích của hình chữ nhật lớn chia 2 return 0; } ``` ::: :::: ::::success > Personal Comment: Domino mentioned ![image](https://hackmd.io/_uploads/S1h9BTCVlx.png) :::: ::::: :::::spoiler Codeforces 71A - Way Too Long Words ::::info **Link:** [71A_CF](https://codeforces.com/problemset/problem/71A/) **ELO:** 800 **Tags:** strings :::: ::::warning **Tóm tắt:** - Nhận vào 1 chuỗi, nếu nó có độ dài hơn 10 thì rút gọn, không thì in ra chuỗi gốc. - Cú pháp rút gọn: Chữ cái đầu + Số ký tự ở giữa + Chữ cái cuối **Ví dụ:** | Input | Output | | -------------------------------------------------------------------------------------------------- | ---------------------------- | | 4<br>word<br>localization<br>internationalization<br>pneumonoultramicroscopicsilicovolcanoconiosis | word<br>l10n<br>i18n<br>p43s | :::: ::::danger **Code (+ Giải thích):** :::spoiler C++ ```cpp= #include <iostream> using namespace std; int main() { int n; // Nhập vào số lượng chuỗi cin >> n; string s; while (n) { // Duyệt qua từng chuỗi cin >> s; // Nhận vào chuỗi gốc if (s.length() > 10) { // Nếu độ dài lớn hơn 10 string r; // Chuỗi đã rút gọn r += s[0]; // Thêm chữ cái đầu vào chuỗi r += to_string(s.length() - 2); // Thêm số chữ đã rút gọn r += s[s.length() - 1]; // Thêm chữ cái cuối vào chuỗi cout << r << endl; // In ra chuỗi đã rút gọn } else cout << s << endl; // In ra chuỗi gốc n--; // Duyệt sang chuỗi tiếp theo } return 0; } ``` ::: :::: ::::success > Personal Comment: Too Long? Bet. ![image](https://hackmd.io/_uploads/BkxIuhaq4le.png) :::: ::::: :::::spoiler Codeforces 112A - Petya and Strings ::::info **Link:** [112A_CF](https://codeforces.com/problemset/problem/112/A) **ELO:** 800 **Tags:** implementation, strings :::: ::::warning **Tóm tắt:** - Cho 2 chuỗi có độ dài bằng nhau, so sánh 2 chuỗi: - Nếu chuỗi đầu lớn hơn chuỗi sau thì in '1' - Nếu chuỗi dầu bé hơn chuỗi sau thì in '-1' - Nếu 2 chuỗi bằng nhau thì in '0' - Không quan trọng in hoa in thường - Cách so sánh: xem 2 chữ cái của 2 chuỗi xem vị trí của 2 tụi nó đứng ở đâu trong bảng chứ cái, từ đó biết lớn bé bằng (kiểu vậy, xem thêm ở [đây](https://en.wikipedia.org/wiki/Lexicographic_order)) **Ví dụ:** | Input | Output | | ------------------ | ------ | | aaaa<br>aaaA | 0 | | abs<br>Abz | -1 | | abcdefg<br>AbCdEfF | 1 | :::: ::::danger **Code (+ Giải thích):** :::spoiler C++ ```cpp= #include <iostream> using namespace std; int main() { string a, b; cin >> a >> b; // Nhập vào 2 chuỗi for (int i = 0; i < a.length(); i++) { // So sánh từng ký tự. Vì độ dài bằng nhau nên i < a.length() hay b.length() cũng được char a_ = a[i], b_ = b[i]; // Tạo ra 2 biến riêng để lưu 2 ký tự đang được lấy để so sánh if (isupper(a[i])) a_ = tolower(a[i]); // Nếu in hoa thì chuyển thành in thường if (isupper(b[i])) b_ = tolower(b[i]); // Nếu in hoa thì chuyển thành in thường if (a_ != b_) { // Nếu 2 ký tự khác nhau cout << ((a_ > b_) ? "1" : "-1") << endl; // Nếu ký tự thuộc chuỗi 1 lớn hơn ký tự thuộc chuỗi 2 thì in ra '1', ngược lại in '-1' // (Ở đây ta đang so sánh bằng bảng mã ASCII*) return 0; } } cout << "0" << endl; return 0; } ``` *: [Bảng mã ASCII](https://en.wikipedia.org/wiki/ASCII) ::: :::: ::::success > Personal Comment: Easy one just work with the strings bruh ![image](https://hackmd.io/_uploads/Syu2xRC4xl.png) :::: ::::: :::::spoiler Codeforces 158A - Next Round ::::info **Link:** [158A_CF](https://codeforces.com/problemset/problem/158/A) **ELO:** 800 **Tags:** special problem, implementation :::: ::::warning **Tóm tắt:** - Cho *n* số - Đếm xem có bao nhiêu số lớn hơn hoặc bằng với số thứ *k*, với điều kiện số thứ *k* lớn hơn 0 **Ví dụ:** | Input | Output | | ----------------------- | ------ | | 8 5<br>10 9 8 7 7 7 5 5 | 6 | | 4 2<br>0 0 0 0 | 0 | :::: ::::danger **Code (+ Giải thích):** :::spoiler C++ ```cpp= #include <iostream> #include <vector> using namespace std; int main() { int n, k; cin >> n >> k; // Nhập vào n (bao nhiêu số), k (số thứ mấy để so sánh) vector<int> a(n); // Lưu các số for (int i = 0; i < n; ++i) { cin >> a[i]; // Nhập vào từng số } int kth = a[k - 1]; // Số thứ k (k - 1 vì trong vector, số đầu tiên đứng ở vị trí thứ 0) int count = 0; // Đếm bao nhiêu số lớn hơn hoặc bằng số thứ k, với điều kiện lớn hơn 0 for (int i = 0; i < n; ++i) { // Duyệt qua từng số if (a[i] >= kth && a[i] > 0) { // Nếu lớn hơn hoặc bằng số thứ k count++; // Tăng 1 vào bộ đếm } else { break; } } cout << count << endl; // In ra bao nhiêu số hợp lệ return 0; } ``` ::: :::: ::::success > Personal Comment: Idk it's just easy i guess... ![image](https://hackmd.io/_uploads/HJOyP3CNel.png) :::: ::::: :::::spoiler Codeforces 169A - Chores ::::info **Link:** [169A_CF](https://codeforces.com/contest/169/problem/A) **ELO:** 800 **Tags:** sortings **Number recommended by:** Đình Tùng (TDN - A2) :::: ::::warning **Tóm tắt:** - P và V được giao *n* việc nhà. - Từng việc nhà có độ khó khác nhau. - P làm việc có độ khó > *x*, V làm việc có độ khó <= *x* - P làm *a* công việc và V làm *b* công việc. - Tính số lượng các giá trị *x*, với *x* là độ khó ở giữa để phân chia công việc cho P và V. **Ví dụ:** | Input | Output | | ---------------------- | ------ | | 5 2 3<br>6 2 3 100 1 | 3 | | 7 3 4<br>1 1 9 1 1 1 1 | 0 | :::: ::::danger **Code (+ Giải thích):** :::spoiler C++ ```cpp= #include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { int n, a, b; cin >> n >> a >> b; // Nhập vào n (bao nhiêu công việc), a (số công việc P làm), b (số công việc V làm) vector<int> h(n); // Lưu các công việc và cấp độ tương ứng for (int i = 0; i < n; i++) { cin >> h[i]; // Nhập vào cấp độ của công việc thứ i } sort(h.begin(), h .end()); // Sắp xếp lại các cấp độ theo thứ tự từ bé đến lớn int result = h[b] - h[b-1]; // Lấy độ khó thấp nhất của công V làm trừ cho độ khó cao nhất của công việc mà P làm, ta sẽ có số lượng các giá trị x cout << result << endl; // In ra số lượng các giá trị x return 0; } ``` ::: :::: ::::success > Personal Comment: Another one got complicated. ![image](https://hackmd.io/_uploads/Hk84Xr0Nee.png) :::: ::::: :::::spoiler Codeforces 231A - Team ::::info **Link:** [231A_CF](https://codeforces.com/problemset/problem/231/A) **ELO:** 800 **Tags:** brute force, greedy :::: ::::warning **Tóm tắt:** - Có *n* bài code. - Có 3 người, nếu có 2/3 hoặc 3/3 người biết giải bài code thì ta sẽ giải bài code đó. - Tính số bài code mà đội 3 người họ có thể giải. **Ví dụ:** | Input | Output | | ---------------------------- | ------ | | 3<br>1 1 0<br>1 1 1<br>1 0 0 | 2 | | 2<br>1 0 0<br>0 1 1 | 1 | :::: ::::danger **Code (+ Giải thích):** :::spoiler C++ ```cpp= #include <iostream> using namespace std; int main() { int n, solve = 0; // Đặt biến solve để lưu số bài code có thể giải cin >> n; // Nhập vào số bài code while (n) { // Duyệt qua từng bài int p, v, t, sure = 0; // Đặt biến cho 3 người và 1 biến để lưu số người giải được bài code cin >> p >> v >> t; // Duyệt qua từng người if (p) sure++; if (v) sure++; if (t) sure++; if (sure > 1) { // Nếu hơn 1 người biết giải solve++; // Thêm 1 vào tổng số bài có thể giải } n--; // Qua bài tiếp theo } cout << solve << endl; // In ra số bài có thể giải bởi đội return 0; } ``` ::: :::: ::::success > Personal Comment: Why can't someone be the MVP and solve all the solutions him/herself lol. ![image](https://hackmd.io/_uploads/HJMMKCiVel.png) :::: ::::: :::::spoiler Codeforces 269A - Beautiful Matrix ::::info **Link:** [269A_CF](https://codeforces.com/problemset/problem/263/A) **ELO:** 800 **Tags:** implementation :::: ::::warning **Tóm tắt:** - Cho một ma trận 5x5 toàn số 0 có một số 1 trong đó, đếm số bước để di chuyển số '1' vào giữa ma trận **Ví dụ:** | Input | Output | | ------------------------------------------------------------- | ------ | | 0 0 0 0 0<br>0 0 0 0 1<br>0 0 0 0 0<br>0 0 0 0 0<br>0 0 0 0 0 | 3 | | 0 0 0 0 0<br>0 0 0 0 0<br>0 1 0 0 0<br>0 0 0 0 0<br>0 0 0 0 0 | 1 | :::: ::::danger **Code (+ Giải thích):** :::spoiler C++ ```cpp= #include <iostream> #include <cmath> using namespace std; int main() { int n = 0, x = 0, y = 1; // Đặt n để lấy số, x để lưu cột của '1' và y để lưu hàng của '1' (đơn giản hơn để hiểu là x y lưu tọa độ của '1' trong ma trận) while (n != 1) { // Khi chưa biết '1' ở đâu thì tiếp tục cho nhập cin >> n; // Nhập vào số x++; // Cộng 1 vào cột if (x == 6) { // Nếu ra khỏi ma trận x = 1; // Về lại ma trận y++; // Cộng 1 vào hàng } } cout << abs(3 - x) + abs(3 - y) << endl; // Vì ma trận luôn là 5x5, muốn vào giữa thì cứ cho '1' về giữa hàng, sau đó vào giữa cột là đến được giữa ma trận. abs() để làm số âm thành số nguyên (ví dụ: 3 - 5 = -2 thì thành 2, đi 2 bước vào giữa) return 0; } ``` ::: :::: ::::success > Personal Comment: Ban đầu làm cho '1' đi từ từ chậm chậm chill chill vào giữa, xong mới nhận ra là phải tìm đường ngắn nhất cho '1' đi ![image](https://hackmd.io/_uploads/rkIpq6CVlg.png) :::: ::::: :::::spoiler Codeforces 282A - Bit++ ::::info **Link:** [282A_CF](https://codeforces.com/problemset/problem/282/A) **ELO:** 800 **Tags:** implementation :::: ::::warning **Tóm tắt:** - Cho *n* câu lệnh. - Câu lệnh có cấu trúc: '\++' / '\--' + 'X' hoặc ngược lại. ("X++" hoặc "++X") - *x* mặc định là 0. - Cho ra kết quả sau khi cộng trừ. **Ví dụ:** | Input | Output | | --------------- | ------ | | 1<br>++X | 1 | | 2<br>X++<br>--X | 0 | :::: ::::danger **Code (+ Giải thích):** :::spoiler C++ ```cpp= #include <iostream> using namespace std; int main() { int n, x = 0; // Đặt biến x mặc định thành 0 cin >> n; // Nhập vào n số câu lệnh while (n) { string stm; cin >> stm; // Nhập vào câu lệnh // Inf IQ move: dù câu lệnh có xáo trộn cỡ nào thì ở giữa chỉ có thể là '+' hoặc '-' if (stm[1] == '+') x++; // Nếu câu lệnh có '+' ở giữa thì cộng 1 vào x else x--; // Nếu không thì chỉ có thể là '-', trừ 1 vào x n--; // Duyệt qua lệnh tiếp theo } cout << x << endl; // In ra kết quả return 0; } ``` ::: :::: ::::success > Personal Comment: Brilliant move from me right there. ![image](https://hackmd.io/_uploads/SJjwnCsVex.png) :::: ::::: :::::spoiler Codeforces 339A - Helpful Maths ::::info **Link:** [339A](https://codeforces.com/problemset/problem/339/A) **ELO:** 800 **Tags:** greedy, implementation, sortings, strings :::: ::::warning **Tóm tắt:** - Cho một phương trình, sắp xếp lại từ bé đến lớn (xem ví dụ bên dưới) **Ví dụ:** | Input | Output | | --------- | --------- | | 3+2+1 | 1+2+3 | | 1+1+3+1+3 | 1+1+1+3+3 | | 2 | 2 | :::: ::::danger **Code (+ Giải thích):** :::spoiler C++ ```cpp= #include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { string s; cin >> s; // Nhập vào phương trình if (s.length() == 1) { // Edge case: nếu chỉ có 1 số cout << s << endl; // In ra lại số đó return 0; } vector<char> c; // Tạo mảng c để lưu từng số trong phương trình for (int i = 0; i < s.length(); i++) { // Duyệt từng ký tự của phương trình if (s[i] != '+') c.push_back(s[i]); // Nếu là dấu '+' thì bỏ qua, không thì là số, thêm vô c } sort(c.begin(), c.end()); // Sắp xếp lại c từ bé đến lớn for (int i = 0; i < c.size(); i++) { // Duyệt qua mảng c if (i == c.size() - 1) cout << c[i]; // Nếu là số cuối thì không in ra dấu '+' ở phía sau else cout << c[i] << '+'; // Không thì in ra số kèm dấu '+' } return 0; } ``` ::: :::: ::::success > Personal Comment: I wonder if Xenia can finally calculate without this now :pray: ![image](https://hackmd.io/_uploads/BJ6vVCC4lx.png) :::: ::::: :::::spoiler Codeforces 236A - Boy or Girl ::::info **Link:** [236A](https://codeforces.com/problemset/problem/236/A) **ELO:** 800 **Tags:** brute force, implementation, strings :::: ::::warning **Tóm tắt:** - Cho 1 chuỗi, đếm xem có bao nhiêu ký tự riêng biệt, nếu: - Là số chẳn thì in ra "CHAT WITH HER!" - Là số lẻ thì in ra "IGNORE HIM!" **Ví dụ:** | Input | Output | | ---------- | -------------- | | wjmzbmr | CHAT WITH HER! | | xiaodao | IGNORE HIM! | | sevenkplus | CHAT WITH HER! | :::: ::::danger **Code (+ Giải thích):** :::spoiler C++ ```cpp= #include <iostream> using namespace std; int main() { string s; cin >> s; // Nhập vào chuỗi int ascii[127] = {0}; // Tạo một mảng để đếm số lần xuất hiện của từng ký tự int distC = 0; // Đếm có bao nhiêu ký tự riêng biệt for (int i = 0; i < s.length(); i++) { // Duyệt qua từng ký tự trong chuỗi if (ascii[s[i]] == 0) distC++; // Nếu ký tự chưa bị trùng thì cộng 1 vào distC ascii[s[i]]++; // Cộng 1 vào số lần xuất hiện của ký tự } // (Ta đang dùng ASCII nên chắc chắn không có việc 2 ký tự riêng biệt được đếm chung) cout << ((distC % 2 == 0) ? "CHAT WITH HER!" : "IGNORE HIM!"); // Xem chẳn hay lẻ rồi in ra kết quả mong muốn của đề bài return 0; } ``` ::: :::: ::::success > Personal Comment: Do NOT use this technique in real life :pray: ![image](https://hackmd.io/_uploads/rkg1aPyHgg.png) :::: ::::: ### 29/06/2025: Các thư viện (Req4): ```cpp= #include <initializer_list> // begin(), end() để có iterator để duyệt qua vector/map/... #include <unordered_map> // map nhưng mà nhanh hơn (không sắp xếp) // find() để tìm, at(key) để lấy value theo key #include <unordered_set> // set nhưng mà nhanh hơn (không sắp xếp) // insert() thêm phần tử và count() kiểm tra có phần tử tồn tại trong set không #include <algorithm> // sort() để sắp xếp, max_element() để tìm phần tử lớn nhất trong mảng/vector/... #include <iostream> // cin để input, cout để output #include <valarray> // tạo một mảng được tối ưu hóa cho các phép toán lên toàn bộ mảng // (nhân chia cộng trừ 2 mảng chẳng hạn) #include <cstring> // strlen() trả về độ dài chuỗi của C, strcpy() sao chép chuỗi của C // (chuỗi của C = chuỗi cũ, chuỗi không tương thích với cpp) #include <numeric> // accumulate() tính tổng các phần tử trong phạm vi, iota() thêm một đống phần tử vào một mảng theo thứ tự tăng dần bắt đầu từ 1 hoặc bất kỳ coder muốn gì #include <iomanip> // setprecision() đặt bao nhiêu số thập phân phía sau khi in ra // fixed đặt chế độ hiển thị số thực #include <complex> // abs() tính độ lớn của số phức, arg() tính góc của số phức // (số phức là j e chưa học) #include <sstream> // stringstream ss cho phép tạo ra một luồng I/O mới riêng cho chuỗi // ss >> variable trích dữ liệu ra khỏi stringstream vào một biến khác #include <cassert> // assert() kiểm tra 1 điều kiện và dừng chương trình nếu điều kiện sai, chỉ hoạt động trong debug mode #include <random> // chứa các engine để random (?) #include <chrono> // làm việc với thời gian, lấy thời gian, đổi đơn vị trong thời gian, tính thời gian #include <vector> // I mean it's mảng but dynamic // push_back() thêm một phần tử vào cuối mảng, pop_back() xóa phần tử ở cuối mảng #include <cstdio> // scanf() hàm đọc của C, printf() hàm in của C #include <bitset> // count() đếm số bit '1', test() kiểm tra trạng thái của bit #include <array> // mảng // fill() điền tất cả phần tử thành 1 giá trị, at() truy cập phần tử #include <queue> // mô phỏng hàng đợi, cái nào vô trc ra trc, vô sau ra sau // push() cho người mới vô xếp hàng ở cuối, pop() cho người đứng đầu đi ra #include <deque> // hàng đợi 2 đầu // push_front() thêm vào đầu, push_back() thêm vào cuối #include <stack> // giống chồng sách, cái nào để lên sau cùng sẽ được lấy lên trước // push() để sách mới lên trên cùng, pop() lấy sách ở trên cùng ra #include <cmath> // sqrt() căn bậc hai, pow() lũy thừa #include <tuple> // một mảng chứa các phần tử có nhiều kiểu dữ liệu khác nhau // get<index>(tuple) truy cập phần tử thứ index trong tuple (cách duy nhất để lấy) #include <regex> // làm việc với chuỗi, dùng một cái gọi là "Regular expression" để so sánh chuỗi hay gì đó không hiểu nữa #include <list> // mảng nhưng mà giữ iterator sau khi bị xóa (?) // insert() và erase() thêm và xóa phần tử tại một vị trí cố định #include <set> // set #include <map> // một phần tử có <key, value> // khá là JSON // Không nên dùng <bits/stdc++.h> và using namespace std vì: // <bits/stdc++.h> thêm TẤT CẢ thư viện chuẩn của C++ vào file cpp của bạn // Điều này đầu tiên nhất là làm chậm thời gian chạy, cùng với đó là bộ nhớ sử dụng nhiều hơn // Thứ hai là khi dùng using namespace std, ta đặt tất cả tên namespace thành std, điều này sẽ gây ra việc trình biên dịch không biết bạn đang muốn dùng thư viện nào cho một hàm nào đó có nhiều namespace // Nói chung là rất nguy hiểm, cứ làm quen với việc bỏ từng thư viện vào là nhớ được không cần phải bit bet j hết ``` Kiểu dữ liệu (SES4): | Kiểu dữ liệu | min | max | số bit | số trạng thái | | ------------ | -------------------------- | -------------------------- | ------ | -------------------------- | | bool | 0 (false) | 1 (true) | 8 | 2 | | char | -128 | 127 | 8 | 256 | | int | -2 147 483 648 | 2 147 483 647 | 32 | 4 294 967 296 | | float | 1.175494351 E - 38 | 3.402823466 E + 38 | 32 | 4,294,967,296 | | long long | -9 223 372 036 854 775 808 | 9 223 372 036 854 775 807 | 64 | 18,446,744,073,709,551,616 | | double | 2.2250738585072014 E - 308 | 1.7976931348623158 E + 308 | 64 | 18,446,744,073,709,551,616 | | void | | | | |