Code bạn (O(N log N)) ← có thể có bug
Code brute force (O(N²)) ← chắc chắn đúng (đơn giản)
Sinh testcase ngẫu nhiên → chạy cả 2 → so output
→ Nếu khác nhau → TÌM RA BUG!
#include<bits/stdc++.h>usingnamespacestd;mt19937rng(chrono::steady_clock::now().time_since_epoch().count());intrandInt(intl,intr){returnuniform_int_distribution<int>(l,r)(rng);}intmain(){// Sinh số ngẫu nhiên trong [a, b]inta=1,b=100;intrandom_num=randInt(a,b);cout<<random_num<<endl;// Sinh mảng ngẫu nhiênintn=10;vector<int>arr(n);for(inti=0;i<n;i++)arr[i]=randInt(1,100);// In testcasecout<<n<<endl;for(intx:arr)cout<<x<<" ";cout<<endl;}
// Sinh testcase cho Binary SearchvoidgenBinarySearch(){intn=randInt(1,100);// 1 ≤ n ≤ 100inttarget=randInt(1,1000);vector<int>arr(n);for(inti=0;i<n;i++)arr[i]=randInt(1,1000);sort(arr.begin(),arr.end());// Đảm bảo mảng tăng dần// In testcasecout<<n<<" "<<target<<endl;for(intx:arr)cout<<x<<" ";cout<<endl;}
// Sinh cây ngẫu nhiên (N đỉnh, N-1 cạnh)voidgenTree(){intn=randInt(2,11);// 2 ≤ n ≤ 11cout<<n<<endl;for(inti=2;i<=n;i++){intparent=randInt(1,i-1);// Cha ngẫu nhiên từ 1..i-1cout<<parent<<" "<<i<<" "<<randInt(1,100)<<endl;}}// Sinh đồ thị ngẫu nhiên (có thể có chu trình)voidgenGraph(){intn=randInt(2,10);intm=randInt(n-1,n*(n-1)/2);cout<<n<<" "<<m<<endl;for(inti=0;i<m;i++){intu=randInt(1,n);intv=randInt(1,n);intw=randInt(1,100);cout<<u<<" "<<v<<" "<<w<<endl;}}
Lặp lại N lần:
1. Sinh testcase ngẫu nhiên
2. Chạy code "đúng" (brute force) → expected
3. Chạy code "cần test" → actual
4. Nếu expected ≠ actual → IN RA TESTCASE ĐÓ → DEBUG!
#include<bits/stdc++.h>usingnamespacestd;// ===== Code brute force (chắc chắn đúng) =====longlongbruteForce(vector<int>&a){// Ví dụ: tìm max subarray sum - O(N²)longlongmaxSum=LLONG_MIN;for(inti=0;i<a.size();i++){longlongsum=0;for(intj=i;j<a.size();j++){sum+=a[j];maxSum=max(maxSum,sum);}}returnmaxSum;}// ===== Code cần test (có thể có bug) =====longlongmySolution(vector<int>&a){// Kadane's algorithm - O(N)longlongmaxSum=a[0],curSum=a[0];for(inti=1;i<a.size();i++){curSum=max((longlong)a[i],curSum+a[i]);maxSum=max(maxSum,curSum);}returnmaxSum;}mt19937rng(chrono::steady_clock::now().time_since_epoch().count());intrandInt(intl,intr){returnuniform_int_distribution<int>(l,r)(rng);}intmain(){for(inttest=1;test<=10000;test++){// Bước 1: Sinh testcase ngẫu nhiênintn=randInt(1,20);vector<int>a(n);for(inti=0;i<n;i++)a[i]=randInt(-100,100);// [-100, 100]// Bước 2: Chạy cả 2longlongexpected=bruteForce(a);longlongactual=mySolution(a);// Bước 3: So sánhif(expected!=actual){cout<<"BUG FOUND at test "<<test<<"!\n";cout<<"Input: n="<<n<<endl;for(intx:a)cout<<x<<" ";cout<<endl;cout<<"Expected: "<<expected<<endl;cout<<"Actual: "<<actual<<endl;return0;}}cout<<"All 10000 tests passed!\n";return0;}
- N = 0 (mảng rỗng)
- N = 1 (mảng 1 phần tử)
- Tất cả phần tử giống nhau
- Mảng tăng dần / giảm dần
- Phần tử âm / dương / 0
- Số rất lớn (10^9) / rất nhỏ (-10^9)
1. Đọc lại đề → hiểu đúng bài toán?
2. Chạy sample test → đúng?
3. Viết brute force
4. Sinh testcase nhỏ → so sánh
5. Nếu tìm ra test sai:
a. In ra input/output expected/actual
b. Debug code với test đó
c. Fix bug
d. Chạy lại stress test
6. Nếu không tìm ra test sai:
a. Tăng số lượng test
b. Tăng kích thước test
c. Thử edge cases thủ công