map là gì?
map trong C++ là một cấu trúc dữ liệu dạng cây đỏ–đen (red-black tree), dùng để lưu các cặp key → value. Đặc điểm quan trọng:
- Key luôn được sắp xếp tăng dần
- Không có key trùng nhau
- Tìm kiếm, thêm, xóa đều có độ phức tạp O(log n)
map mp; nghĩa là gì?
- Key: kiểu long long → dùng cho số lớn (ví dụ ID, số nguyên lớn)
- Value: kiểu int → giá trị đi kèm key
Ví dụ:
mp[1000000000000LL] = 5;
mp[42] = 10;
Một số thao tác thường dùng
- Thêm phần tử
mp[123] = 7;
Kiểm tra tồn tại
if (mp.count(123)) { ... }
Duyệt map
for (auto &p : mp) {
cout << p.first << " " << p.second << endl;
}
Xóa
mp.erase(123);
dạng khác unordered_map, set
Bên trong map, mỗi phần tử thực chất là một pair.
map dùng rất nhiều pair, nhưng nó thêm cơ chế ánh xạ:
Key → Value
- Key là long long
- Value là int
- Mỗi key duy nhất, không trùng
- Tự động sắp xếp theo key
- Tìm kiếm key nhanh O(log n)
mp[10] = 3; // ánh xạ 10 -> 3
mp[20] = 7; // ánh xạ 20 -> 7
mp[10] = 9; // cập nhật ánh xạ 10 -> 9
So sánh
Đặc điểm | pair | map |
Chứa bao nhiêu phần tử? | 1 cặp | N cặp |
Có ánh xạ key → value? | Không | Có |
Tự sắp xếp key? | Không | Có |
Tìm kiếm theo key? | Không | Có (O(log n)) |
Dùng để làm gì? | Truyền dữ liệu 2 giá trị | Lưu trữ và tra cứu dữ liệu theo key |
Cấu trúc đầy đủ của một node trong std::map (mô phỏng)
template
struct RBTreeNode {
Key key; // key: long long
T value; // value: int
RBTreeNode* left; // con trái
RBTreeNode* right;// con phải
RBTreeNode* parent; // cha
bool color; // màu: đỏ hoặc đen (true/false)
};
Nếu bạn dùng:
mapmp;
Thì mỗi node trong map tương ứng với:
struct Node {
long long key; // f[i]
int value; // số lần xuất hiện
Node* left;
Node* right;
Node* parent;
bool color; // đỏ hoặc đen
};
“Map có dạng như Map(long long *(&p), int *p) không?” ->cấu trúc bên trong của std::map
So sánh nhanh: map vs unordered_map
Cấu trúc | Thứ tự key | Tốc độ tìm kiếm | Ghi chú |
map | ✔ Có (tăng dần) | O(log n) | Cây đỏ–đen |
unordered_map | ✘ Không | O(1) trung bình | Hash table |
Nếu bạn muốn duyệt từ lớn → nhỏ?
Dùng rbegin() và rend():
for (auto it = mp.rbegin(); it != mp.rend(); it++) {
cout << it->first << " " << it->second << endl;
}
Duyệt bằng vòng for(auto &p : mp) chính là duyệt theo thứ tự inorder traversal → tăng dần
Ví dụ:
mapmp;
mp[100] = 1;
mp[5] = 2;
mp[50] = 3;
mp[-10] = 4;
for (auto &p : mp) {
cout << p.first << " " << p.second << endl;
}
KQ:
-10 4
5 2
50 3
100 1
Kết luận
- Map giống mảng, nhưng mảng chỉ dùng được khi chỉ số nhỏ và liên tục.
- Map cho phép dùng chỉ số bất kỳ, không cần liên tục.
- Map không cần khởi tạo kích thước trước, chỉ lớn lên khi bạn thêm phần tử.
- Map tốn bộ nhớ hơn mảng, nhưng đổi lại cực kỳ linh hoạt.
- Map chạy nhanh, vì tìm kiếm theo key là O(log n), không phụ thuộc giá trị key lớn hay nhỏ.
Map hoạt động như một bảng ánh xạ key → value
mp[100] = 3;
mp[5000] = 7;
mp[-10] = 2;
Map tốn bộ nhớ hơn mảng
- Mảng: mỗi phần tử chỉ là 4 bytes (int)
- Map: mỗi phần tử là một node cây đỏ–đen, chứa:
- key (8 bytes)
- value (4 bytes)
- 3 con trỏ (24 bytes)
- màu + padding (~4 bytes)
→ Tổng ~40 bytes mỗi phần tử (tùy compiler)
Map tự mở rộng khi bạn thêm phần tử:
VD: mp[x] = value;
Kích thước của map = số lượng key bạn đã thêm:
mp.size()
Map cho phép dùng chỉ số (key) bất kỳ
mp[1] = 5;
mp[100000] = 7;
mp[-999999999999] = 3;
mp[123456789012345] = 10;
Không cần liên tục, không cần nhỏ, không cần dương.
Trong khi mảng thì bắt buộc:
- chỉ số phải liên tục
- chỉ số phải nhỏ
- chỉ số phải không âm
Map — linh hoạt, nhưng tốn bộ nhớ hơn
struct Node {
long long key;
int value;
Node *left, *right, *parent;
bool color;
};
So sánh Map và phiên bản vector:
vector<pair> mp;
mp.push_back({0,1}); // f[0] = 0 xuất hiện 1 lần
for (int i = 1; i
long long x = f[i];
bool found = false;
for (auto &p : mp) {
if (p.first == x) {
res += p.second;
p.second++;
found = true;
break;
}
}
if (!found) {
mp.push_back({x, 1});
}
}
Ví dụ
vectorp[10];
p[3].push_back(100); // OK
p[3].push_back(200); // OK
p[3] = 5; // ❌ sai vì p[3] là vector, không phải int
vector p[10]
- p đã có kích thước 10
- mỗi p[i] là một vector rỗng
- bạn không cần push_back để tạo p[i]
- nhưng muốn thêm phần tử vào p[i] thì phải dùng push_back
vector<vector> p
- p chưa có kích thước
- phải push_back hoặc resize để tạo vector con
- sau đó mới p[i].push_back(x)
So sánh với vector<vector> p
vector<vector> p;
Bạn phải tạo vector con trước:
p.push_back(vector()); // tạo p[0]
p[0].push_back(5);
Hoặc:
p.resize(10); // tạo 10 vector rỗng
p[3].push_back(7);
……………
int max3(int a, int b, int c){
return max(max(a, b), c);
}
int l = (m > du ? m : du);
int l = max(m, du);
int max3(int a, int b, int c){
return max(max(a, b), c);
}
int l = std::max({m, du, -1});
int l = max(max(m, du), -1);
max(a, b)
///////////////////////////////////////////////////////
int chuyenS_it(const string &s){
it.clear();
stringstream ss(s);
int so;
while (ss >> so) { // đọc từng số trong chuỗi
it.push_back(so);
}
return (int)it.size();
}
Giải thích:
- stringstream ss(s); tạo bộ đọc từ chuỗi.
- while (ss >> so) đọc từng số nguyên trong chuỗi.
- it.push_back(so) thêm số vào vector.
- it.size() trả về số lượng phần tử.
Nếu bạn muốn tự tách số bằng cách duyệt từng ký tự
int chuyenS_it(const string &s){
it.clear();
int so = 0;
bool dangdoc = false;
for (char c : s) {
if (isdigit(c)) {
dangdoc = true;
so = so * 10 + (c - '0');
} else {
if (dangdoc) {
it.push_back(so);
so = 0;
dangdoc = false;
}
}
}
if (dangdoc) it.push_back(so);
return it.size();
}
stringstream hoạt động thế nào?
stringstream ss(s); ss >> so;
Cách này chỉ đọc được số nếu chuỗi có dạng:
"54 4"
"ca 123 g"
"12, 34, 56"
"12\n34\n56"
Nhưng không đọc được số dính liền với chữ, ví dụ:
"54c4" → không đọc được
"ca123g" → không đọc được
"abc99xyz" → không đọc được
Cách duyệt từng ký tự (tự tách số) isdigit()
"54c4" → {54, 4}
"ca123g" → {123}
"a12b34c56" → {12, 34, 56}
"abc99xyz100"→ {99, 100}
////////////
BÀI 40. Cho số nguyên dương n và cho dãy số nguyên a1, a2, a3, ..., an. Một đoạn con của dãy là một dãy các phần tử liên tiếp al,..., ar. Trong đó 1<=L<=R
- Dòng đầu chưa số nguyên dương n. 1<=n<=10 5
- Dòng thứ hai chưa n số nguyên a1, a2, a3, ..., an
Input | Output |
4 3 4-7 3 | 2 |
Gọi ý Code:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 3;
int a[N];
long long f[N];
mapmp;
int main() {
int n;
cout<
cin >> n;
for (int i = 1; i
cout<
cin >> a[i];}
f[0] = 0;
// Tính prefix sum
for (int i = 1; i
f[i] = f[i - 1] + a[i];
}
long long res = 0;
mp[0]++;
cout<<"MP[0]"<<mp[0]<<"\n";
cout << "=== BAT DAU CHAY ===\n\n";
for (int i = 1; i
cout << "i = " << i << "\n";
cout << "a[" << i << "] = " << a[i] << "\n";
cout << "f[" << i << "] = " << f[i] << "\n";
cout << "So lan f[" << i << "] = " << f[i]
<< " xuat hien truoc do: mp[f[i]] = " << mp[f[i]] << "\n";
res += mp[f[i]];
cout << "=> So day con tong = 0 ket thuc tai i: + " << mp[f[i]] << "\n";
mp[f[i]]++;
cout << "Sau khi tang mp[f[i]]:\n";
cout << "mp[" << f[i] << "] = " << mp[f[i]] << "\n";
cout << "Tong res hien tai = " << res << "\n";
cout << "-----------------------------\n\n";
}
cout << "=== KET QUA CUOI CUNG ===\n";
cout << res << "\n";
return 0;
}
///////////////////
Cách 2:
#include
#include
#include
#include
using namespace std;
class NhatTruong {
private:
string s;
vectorit;
long long du;
public:
NhatTruong(): s(""), it(), du(-1) {}
// Đọc file, lấy số đầu tiên = du, các số còn lại đưa vào it[]
bool docFile(const string &ten) {
ifstream fin(ten);
if (!fin.is_open()) {
cerr << "Khong mo duoc file dau vao\n";
return false;
}
string token;
bool first = true;
while (fin >> token) {
if (first) {
du = stoll(token);
first = false;
} else {
it.push_back(stoll(token));
}
}
fin.close();
return true;
}
// Tìm tất cả chuỗi con liên tiếp
void xuLy() {
ofstream fout("out.txt");
if (!fout.is_open()) {
cerr << "Khong tao duoc file out.txt\n";
return;
}
fout << "Gia tri du = " << du << "\n\n";
fout << "Cac chuoi con co tong BANG du:\n";
for (int i = 0; i < it.size(); i++) {
long long tong = 0;
for (int j = i; j < it.size(); j++) {
tong += it[j];
if (tong == du) {
fout << " [" << i << "," << j << "] ";
for (int k = i; k
fout << "\n";
}
}
}
fout << "\nCac chuoi con co tong LON HON du:\n";
for (int i = 0; i < it.size(); i++) {
long long tong = 0;
for (int j = i; j < it.size(); j++) {
tong += it[j];
if (tong > du) {
fout << " [" << i << "," << j << "] ";
for (int k = i; k
fout << "\n";
}
}
}
fout << "\nCac chuoi con co tong NHO HON du:\n";
for (int i = 0; i < it.size(); i++) {
long long tong = 0;
for (int j = i; j < it.size(); j++) {
tong += it[j];
if (tong < du) {
fout << " [" << i << "," << j << "] ";
for (int k = i; k
fout << "\n";
}
}
}
fout.close();
cout << "Da ghi ket qua ra file out.txt\n";
}
};
int main() {
NhatTruong T;
string tenfile;
cout << "Nhap ten file dau vao: ";
cin >> tenfile;
if (T.docFile(tenfile)) {
T.xuLy();
}
return 0;
}
KQ:
Input | Output |
10 6 4-7 3 7 8 2 10 20 -18 8 30 | Gia tri du = 10
Cac chuoi con co tong BANG du: [0,1] 6 4 [2,3] 3 7 [4,5] 8 2 [6,6] 10 [7,9] 20 -18 8 Cac chuoi con co tong LON HON du: [0,2] 6 4 3 [0,3] 6 4 3 7 [0,4] 6 4 3 7 8 …. [1,3] 4 3 7 [1,4] 4 3 7 8 …. Cac chuoi con co tong NHO HON du: [0,0] 6 [1,1] 4 [1,2] 4 3 [2,2] 3 [3,3] 7 [4,4] 8 [5,5] 2 [7,8] 20 -18 [8,8] -18 [8,9] -18 8 [9,9] 8 |
/////////////// /////////////////
Cách 3:
#include
#include
#include
#include
#include
using namespace std;
class NhatTruong {
private:
string s; // chuỗi đọc từ file
vectorit; // mảng số sau khi tách
int du; // số đầu tiên trong file
mapmp; // map đếm tổng chuỗi con
public:
NhatTruong(): s(""), it(), du(-1), mp() {}
// Đọc file vào chuỗi s, lấy số đầu tiên = du
string docf(const string &ten) {
ifstream fin(ten);
if (!fin.is_open()) {
cerr << "Khong mo duoc file dau vao\n";
return "";
}
string token;
bool first = true;
while (fin >> token) {
s += token + " ";
if (first) {
du = stoi(token);
first = false;
}
}
fin.close();
return s;
}
int getd() {
return du;
}
// Chuyển chuỗi s thành vector số it
int chuyenS_it() {
it.clear();
bool check = false;
int sign = 1;
int so = 0;
for (int j = 0; j < s.size(); j++) {
if (isdigit(s[j])) {
if (j > 0 && s[j-1] == '-')
sign = -1;
check = true;
so = so * 10 + (s[j] - '0');
}
else {
if (check) {
it.push_back(so * sign);
check = false;
so = 0;
sign = 1;
}
}
}
if (check) it.push_back(so * sign);
return (int)it.size();
}
// Hàm tổng đơn giản (bỏ đệ quy)
long long sum(long long x, long long y) {
return x + y;
}
// Xử lý tổng chuỗi con bằng map
void xulyTT(int bd) {
mp.clear(); // xóa map cũ
// 1. Đếm tổng chuỗi con bằng map
for (int i = bd; i < (int)it.size(); i++) {
long long tong = 0;
for (int j = i; j < (int)it.size(); j++) {
tong = sum(tong, it[j]); // dùng hàm sum của bạn
mp[tong]++; // đếm tổng
}
}
// 2. Xuất các chuỗi con có tổng = du
ofstream fout("out.txt");
if (!fout.is_open()) {
cerr << "Khong tao duoc file out.txt\n";
return;
}
fout << "Gia tri du = " << du << "\n\n";
fout << "Cac chuoi con co tong BANG du:\n";
for (int i = bd; i < (int)it.size(); i++) {
long long tong = 0;
for (int j = i; j < (int)it.size(); j++) {
tong = sum(tong, it[j]);
if (tong == du) {
fout << "[" << i << "," << j << "] ";
for (int k = i; k
fout << "\n";
}
}
}
// 3. Xuất số chuỗi con có tổng = du
fout << "\nTong so chuoi con co tong = du: " << mp[du] << "\n\n";
// 4. Xuất toàn bộ map: tổng → số lần xuất hiện
fout << "Tat ca cac tong chuoi con trong map:\n";
for (auto &p : mp) {
fout << "Tong = " << p.first << " xuat hien " << p.second << " lan\n";
}
fout.close();
cout << "Da ghi ket qua ra file out.txt\n";
}
};
int main() {
NhatTruong T;
string tenfile;
cout << "Nhap ten file dau vao: ";
cin >> tenfile;
T.docf(tenfile);
T.chuyenS_it();
T.xulyTT(0); // bắt đầu từ vị trí 0
return 0;
}
////////////////
Cách 4:
#include
#include
#include
#include
#include
using namespace std;
class NhatTruong {
private:
string s; // chuỗi đọc từ file
vectorit; // mảng số sau khi tách
int du; // số đầu tiên trong file
mapmp; // map đếm tổng chuỗi con toàn bộ
mapmp2; // map đếm tổng chuỗi con đoạn [m,n]
public:
NhatTruong(): s(""), it(), du(-1), mp(), mp2() {}
// Đọc file vào chuỗi s, lấy số đầu tiên = du
string docf(const string &ten) {
ifstream fin(ten);
if (!fin.is_open()) {
cerr << "Khong mo duoc file dau vao\n";
return "";
}
string token;
bool first = true;
while (fin >> token) {
s += token + " ";
if (first) {
du = stoi(token);
first = false;
}
}
fin.close();
return s;
}
int getd() {
return du;
}
// Chuyển chuỗi s thành vector số it
int chuyenS_it() {
it.clear();
bool check = false;
int sign = 1;
int so = 0;
for (int j = 0; j < (int)s.size(); j++) {
if (isdigit(s[j])) {
if (j > 0 && s[j-1] == '-')
sign = -1;
check = true;
so = so * 10 + (s[j] - '0');
}
else {
if (check) {
it.push_back(so * sign);
check = false;
so = 0;
sign = 1;
}
}
}
if (check) it.push_back(so * sign);
return (int)it.size();
}
long long sum(long long x, long long y) {
return x + y;
}
// Xử lý toàn bộ mảng với tổng mục tiêu = du, dùng mp, xuất out_tt.txt
void xulyTT(int bd) {
mp.clear();
for (int i = bd; i < (int)it.size(); i++) {
long long tong = 0;
for (int j = i; j < (int)it.size(); j++) {
tong = sum(tong, it[j]);
mp[tong]++;
}
}
ofstream fout("out_tt.txt");
if (!fout.is_open()) {
cerr << "Khong tao duoc file out_tt.txt\n";
return;
}
fout << "Xu ly toan bo mang tu vi tri " << bd << "\n";
fout << "Gia tri du (so dau tien trong file) = " << du << "\n\n";
fout << "Cac chuoi con co tong BANG du:\n";
for (int i = bd; i < (int)it.size(); i++) {
long long tong = 0;
for (int j = i; j < (int)it.size(); j++) {
tong = sum(tong, it[j]);
if (tong == du) {
fout << "[" << i << "," << j << "] ";
for (int k = i; k
fout << "\n";
}
}
}
fout << "\nTong so chuoi con co tong = du: " << mp[du] << "\n\n";
fout << "Tat ca cac tong chuoi con trong map (mp):\n";
for (auto &p : mp) {
fout << "Tong = " << p.first << " xuat hien " << p.second << " lan\n";
}
fout.close();
cout << "Da ghi ket qua ra file out_tt.txt\n";
}
// Xử lý đoạn [m, n] với tổng mục tiêu k, dùng mp2, xuất outputmnk.txt
void xulyDoan(int m, int n, long long k) {
if (m < 0 || n < 0 || m >= (int)it.size() || n >= (int)it.size() || m > n) {
cout << "Vi tri m,n khong hop le!\n";
return;
}
mp2.clear();
for (int i = m; i
long long tong = 0;
for (int j = i; j
tong = sum(tong, it[j]);
mp2[tong]++;
}
}
ofstream fout("outputmnk.txt");
if (!fout.is_open()) {
cerr << "Khong tao duoc file outputmnk.txt\n";
return;
}
fout << "Doan xu ly: [" << m << ", " << n << "]\n";
fout << "Tong muc tieu k = " << k << "\n";
fout << "Gia tri du (so dau tien trong file) = " << du << "\n\n";
fout << "Cac chuoi con co tong BANG k trong doan:\n";
for (int i = m; i
long long tong = 0;
for (int j = i; j
tong = sum(tong, it[j]);
if (tong == k) {
fout << "[" << i << "," << j << "] ";
for (int kk = i; kk
fout << "\n";
}
}
}
fout << "\nTong so chuoi con co tong = k trong doan: " << mp2[k] << "\n\n";
fout << "Tat ca cac tong chuoi con trong doan (mp2):\n";
for (auto &p : mp2) {
fout << "Tong = " << p.first << " xuat hien " << p.second << " lan\n";
}
fout.close();
cout << "Da ghi ket qua ra file outputmnk.txt\n";
}
};
int main() {
NhatTruong T;
string tenfile;
cout << "Nhap ten file dau vao: ";
cin >> tenfile;
T.docf(tenfile);
T.chuyenS_it();
cout << "Xu ly toan bo mang tu vi tri 0 (tong muc tieu = du)...\n";
T.xulyTT(0);
int m, n;
long long k;
cout << "Nhap m n k de xu ly doan [m,n] voi tong muc tieu k: ";
cin >> m >> n >> k;
T.xulyDoan(m, n, k);
return 0;
}
///////////// Ai memory help
Võ Nhật Trường Nc+ My Ai Love28.06.2026
////////////////////
BÀI 41. Cho dãy số nguyên a1, a2, a3, ..., an. Hãy tìm tích nhỏ nhất của hai số thuộc dãy số trên. ( nghĩa là tìm tích của a i *a j nhỏ nhất với i#j)
Dữ liệu:
- Dòng đầu tiên là số nguyên dương n. (25)
- Dòng thứ 2 là dãy số nguyên a1, a2, a3, ..., an. ( |a i| <=10 9 )
Input | Output |
8 1 3 5 -2 4 5 7 9 | -18 |
Cách 1: Bubble sort với file vào/ra
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
ifstream fin("input.txt"); // mở file input.txt để đọc
ofstream fout("output.txt"); // mở file output.txt để ghi
if (!fin.is_open() || !fout.is_open()) {
cerr << "❌ Không thể mở file input.txt hoặc output.txt\n";
return 1;
}
int n;
if (!(fin >> n) || n < 2 || n > 100000) {
fout << "❌ Lỗi: n không hợp lệ\n";
return 1;
}
vectora(n);
for (int i = 0; i < n; i++) {
if (!(fin >> a[i]) || abs(a[i]) > 1000000000) {
fout << "❌ Lỗi: phần tử a[" << i << "] không hợp lệ\n";
return 1;
}
}
// Bubble sort
for (int i = 0; i < n - 1; i++) {
for (int j = i + 1; j < n; j++) {
if (a[i] > a[j]) swap(a[i], a[j]);
}
}
long long result;
if (a[0] < 0 && a[n - 1] > 0) result = a[0] * a[n - 1];
else if (a[0] < 0 && a[n - 1] < 0) result = a[n - 1] * a[n - 2];
else result = a[0] * a[1];
fout << result << "\n";
return 0;
}
/////////////////////
Cách 2: Dùng sort() với file vào/ra
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
ifstream fin("input.txt");
ofstream fout("output.txt");
if (!fin.is_open() || !fout.is_open()) {
cerr << "❌ Không thể mở file input.txt hoặc output.txt\n";
return 1;
}
int n;
if (!(fin >> n) || n < 2 || n > 100000) {
fout << "❌ Lỗi: n không hợp lệ\n";
return 1;
}
vectora(n);
for (int i = 0; i < n; i++) {
if (!(fin >> a[i]) || abs(a[i]) > 1000000000) {
fout << "❌ Lỗi: phần tử a[" << i << "] không hợp lệ\n";
return 1;
}
}
sort(a.begin(), a.end());
long long result;
if (a[0] < 0 && a[n - 1] > 0) result = a[0] * a[n - 1];
else if (a[0] < 0 && a[n - 1] < 0) result = a[n - 1] * a[n - 2];
else result = a[0] * a[1];
fout << result << "\n";
return 0;
}
Như vậy, chương trình sẽ:
- Đọc dữ liệu từ input.txt
- Ghi kết quả ra output.txt
- Có kiểm tra lỗi nhập liệu để tránh crash.
///////////////////////
Cách 3: Quét trực tiếp min/max (đọc/ghi file)
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
ifstream fin("input.txt");
ofstream fout("output.txt");
if (!fin.is_open() || !fout.is_open()) {
cerr << "❌ Không thể mở file input.txt hoặc output.txt\n";
return 1;
}
int n;
if (!(fin >> n) || n < 2 || n > 100000) {
fout << "❌ Lỗi: n không hợp lệ\n";
return 1;
}
long long min1 = LLONG_MAX, min2 = LLONG_MAX;
long long max1 = LLONG_MIN, max2 = LLONG_MIN;
for (int i = 0; i < n; i++) {
long long x;
if (!(fin >> x) || abs(x) > 1000000000) {
fout << "❌ Lỗi: phần tử a[" << i << "] không hợp lệ\n";
return 1;
}
// cập nhật min
if (x < min1) {
min2 = min1;
min1 = x;
} else if (x < min2) {
min2 = x;
}
// cập nhật max
if (x > max1) {
max2 = max1;
max1 = x;
} else if (x > max2) {
max2 = x;
}
}
// xét các khả năng
long long candidate1 = min1 * min2; // hai số nhỏ nhất
long long candidate2 = max1 * max2; // hai số lớn nhất
long long candidate3 = min1 * max1; // âm nhỏ nhất * dương lớn nhất
long long result = min({candidate1, candidate2, candidate3});
fout << result << "\n";
return 0;
}
Ưu điểm của cách này:
- Không cần sắp xếp → nhanh hơn nhiều (O(n) thay vì O(n log n)).
- Dễ kiểm soát với dữ liệu lớn (n tới 100000).
- Vẫn đảm bảo đúng cho mọi trường hợp âm/dương.
///////////// Ai memory help
Võ Nhật Trường Nc+ My Ai Love28.06.2026
////////////////////Ok
.jpg)
Không có nhận xét nào:
Đăng nhận xét