Một số bài tập C _C++ NC 2026P23











 BÀI 68. Kiểm tra một sâu có phải là sâu đối xứng

BÀI LÀM

#include <bits/stdc++.h>

 

using namespace std;

string s;

 

int main(){

    cout<

    cin>>s;

    string check="";

    for(int i=s.length()-1;i>=0;i--){

        check+=s[i];

    }

    if(check==s) cout<

    else cout << "day khong phai day doi xung";

    return 0;

}

CÁCH 2

#include <bits/stdc++.h>

 

using namespace std;

string s;

 

int main(){

    cout<

    cin>>s;

    bool check=true;

    int l=s.length();

    for(int i=0;i<s.length()/2;i++){

        if(s[i]!=s[l-1-i]){

            check=false;

            break;

        }

    }

    if(check==true) cout<

    else cout << "day khong phai day doi xung";

    return 0;

}

Bài 69. Cho mảng gồm n phần tử . Hãy liệt kê các cặp phần tử có tổng bằng s.

Input

Output

10

12

4 5 6 7 8 9 10 12 11 15

 

 

4,8

5,7

BÀI LÀM

#include<bits/stdc++.h>

using namespace std;

long long n,a[100005];

long long s;

long long dem=0;

int main(){

    cin>>n;

    cin>>s;

    for (int i= 1; i

        cin>>a[i];

    for (int i=1; i< n; i++)

        for (int j= i+1; j

           if((a[i]+a[j])==s) dem++;

         if((a[i]+a[j])==s) cout <<a[i]<<","<<a[j]<<endl;

        }

         if(dem!=0) cout<<endl;

         else cout<<"-1";

    return 0;

}

Bài 69.b. Cho mảng gồm n phần tử . Hãy đếm các cặp phần tử có tổng bằng s.

( trong dãy có tổng không bằng s thì đưa ra -1)

Input

Output

8

10

234 55 66 88 99 12 18 11

(10

12

2 3 4 5 6 7 8 9 10 11)

-1

 

 

 

4

BÀI LÀM

#include<bits/stdc++.h>

using namespace std;

long long n,a[100005];

long long s, dem;

int main(){

    cin>>n;

    cin>>s;

    for (int i= 1; i

        cin>>a[i];

    for (int i=1; i< n; i++)

        for (int j= i+1; j

           if((a[i]+a[j])==s) dem ++;

         }

         if(dem> 0)cout<<dem;

         else cout<< "-1";

    return 0;

}

///////////// Ai memory help

Võ Nhật Trường Nc+ My Ai Love06.07.2026

////////////////////

Bài 70

Cho dãy số gồm n số nguyên  a1, a2, …, an và 2 số nguyên không âm L, R (L ≤ R).

Yêu cầu: Đếm số cặp (i, j) thỏa mãn điều kiện: i < j và L ≤ |ai+…+aj| ≤ R .

Dữ liệu vào: Từ file văn bản cb70.txt gồm:

          Hai số nguyên đầu file là giá trị L, R (0 ≤ L ≤ R  ≤ 107)

          Các số nguyên tiếp theo là mảng: a1, a2,…, an (ai ≤ 107)

Kết quả: Ghi ra file văn bản cb70out.txt thông báo kết quả (i,j) >>tong

#include

#include

#include

using namespace std;

vectorTM(vectoraa){

              vectorvi={0};

              int sum=0;

              for(int c:aa){

                     sum+=c;

                     vi.push_back(sum);

              } return vi;        

}

int main(int argc, char** argv) {

              cout<

              cout<

              ifstream fin("cb70.txt");

              if (!fin.is_open()) {

              cerr<

              return 0;}

              int L, R, x;

              fin>>L>>R;

              if(L*RR||L>1e7||R>1e7){

                     cerr<

              for (int i=1;i<=n-1;i++){

                     for (int j=i+1;j<=n;j++){

                               int y=abs(vv[j]-vv[i-1]);

                               if(y>=L&&y

                     }

              }

              ofstream fout("cn70out.txt");

              fout<

              for (int i=1;i<=n-1;i++){

                     for (int j=i+1;j<=n;j++){

                               int y=abs(vv[j]-vv[i-1]);

                               if(y>=L&&y

                     }

              }

              return 0;

}           

///////////// Ai memory help

Võ Nhật Trường Nc+ My Ai Love05.07.2026

////////////////////

Bài 71. ( dãy con tăng dài nhất và chia hết cho số trước nó không liên tiếp)

Một dãy gồm N số nguyên dương a1,a2,...,an được gọi là dãy con hoàn toàn nếu aj chia hết cho ai với mọi j>i, ví dụ dãy 3, 15, 60, 720 là dãy con hoàn toàn (dãy không liên tiếp)

Yêu cầu: Tìm dãy con hoàn toàn có độ dài lớn nhất.

Dữ liệu vào: dãy số nguyên a1,a2,...,an. Mỗi số cách nhau một dấu cách.

Dữ liệu ra: ghi ra file kqcb71.txt độ dài lớn nhất dãy con hoàn toàn.

Ví dụ: file cb71.txt  10 2 3 4 8 9 27 145 81 320 1 3 5 7 9 2 4 8 16 1 23 79 14 39 145 76 320

Gợi ý code:

#include

#include

#include

using namespace std;

int ddc(vectordc){

          int max=0;

          int l=0;

          int r=dc.size()-1;

          for(int j=dc.size()-1;j>0;j--){

                     int max1=0;

                     for (int i=0; i<=j;i++){

                               if(dc[j]%dc[i]==0) max1++;

                     } if(max

                     max=max1;

                     r=j;

                     l=r-max1+1;

          }       

} return max;        

}

 

int main(int argc, char** argv){

          cout<

          cout<

          ifstream fin("cb71.txt");

          if (!fin.is_open()) {

          cerr<

          return 0;}

          int x;

          vectorv;

          while(fin>>x){

                     if(x2e8) {

                     cerr<<"so "<<x<

                     continue;}

                     v.push_back(x);

          } fin.close();

          int zv=v.size()-1;

          vectorvv;

          int L,R,max=0;

          for (int i=0;i<zv;i++){

                     vv.clear();

                     L=i;R=i;

                     vv.push_back(v[i]);

                     for(int j=i+1;j<=zv;j++){

                               if(v[j]>v[R]){

                                         vv.push_back(v[j]);

                                         R=j;

                               }

                     }

                     if(max

          }

          cout<

          ofstream fout("kqcb71.txt");

          fout<

          fout.close();

          return 0;

}

 

/////////////////

Cách 2: thông báo độ dài dãy con hoàn toàn và các phần tử mảng

#include

#include

#include

using namespace std;

vectorddc(vectordc){

          vectortemp;

          int max=0;

          int l=0;

          int r=dc.size()-1;

          for(int j=dc.size()-1;j>0;j--){

                     int max1=0;

                     for (int i=0; i<=j;i++){

                               if(dc[j]%dc[i]==0) max1++;

                     } if(max

                     max=max1;

                     r=j;

          }       

}

          for (int i=0;i

          if(dc[r]%dc[i]==0) temp.push_back(dc[i]);}

          return temp;

}

 

int main(int argc, char** argv){

          cout<

          cout<

          ifstream fin("cb71.txt");

          if (!fin.is_open()) {

          cerr<

          return 0;}

          int x;

          vectorv;

          while(fin>>x){

                     if(x2e8) {

                     cerr<<"so "<<x<

                     continue;}

                     v.push_back(x);

          } fin.close();

          int zv=v.size()-1;

          vectorvv,kq;

          int L,R,max=0;

          for (int i=0;i<zv;i++){

                     vv.clear();

                     L=i;R=i;

                     vv.push_back(v[i]);

                     for(int j=i+1;j<=zv;j++){

                               if(v[j]>v[R]){

                                         vv.push_back(v[j]);

                                         R=j;

                               }

                     }

                     if(max

                     max=ddc(vv).size();

                     kq=ddc(vv);

          }}

          cout<

          cout<

    cout<<endl;

          ofstream fout("kqcb71.txt");

          fout<

          fout<

    for(int val : kq) fout<<val<<" ";

    fout<<endl;

          fout.close();

          return 0;

}

//////////////////////////

Cách 3:

#include

#include

#include

using namespace std;

 

vectorddc(vectordc){

    vectorbest;

    vectortemp;

    for (int i = 0; i < dc.size(); i++) {

        temp.clear();

        temp.push_back(dc[i]);

        for (int j = i+1; j < dc.size(); j++) {

            if (dc[j] % temp.back() == 0 /*&& dc[j] > temp.back()*/) {

                temp.push_back(dc[j]);

            }

        }

        if (temp.size() > best.size()) best = temp;

    }

    return best;

}

 

int main(){

    cout<

    ifstream fin("cb71.txt");

    if (!fin.is_open()) {

        cerr<

        return 0;

    }

    int x;

    vectorv;

    while(fin>>x){

        if(x2e8) {

            cerr<<"so "<<x<

            continue;

        }

        v.push_back(x);

    }

    fin.close();

 

    vectorresult = ddc(v);

 

    cout<

    cout<

    for(int val : result) cout<<val<<" ";

    cout<<endl;

 

    ofstream fout("kqcb71.txt");

    fout<

    fout<

    for(int val : result) fout<<val<<" ";

    fout<<endl;

    fout.close();

 

    return 0;

}

Chú ý:

Nếu em muốn giữ đúng ý bài toán (chỉ tăng dần, không cho phép bằng nhau), thì cần thêm điều kiện dc[j] > temp.back() vào đoạn kiểm tra:

if (dc[j] % temp.back() == 0 && dc[j] > temp.back()) {

    temp.push_back(dc[j]);

}

///////////// Ai memory help

Võ Nhật Trường Nc+ My Ai Love06.07.2026

////////////////////

Bài 72.  Cho dãy gồm số nguyên a1, a2, a3, ..... (|ai|<=10 9 ) Hãy đếm và đưa ra số đặc biệt trong dãy a. Số đặc biệt là số chỉ xuất hiện đúng 1 lần trong dãy số.

Vd: Đầu vào file: Cb72.txt có dữ liệu: 2 3 4 8 9 7 5 8 3 5

Đầu ra:  file: KQcb72.txt sẽ là:  4  ||  2 4 9 7

BÀI LÀM

#include

#include

#include

#include

// #include <bits/stdc++.h>

using namespace std;

int main(){

mapma;

vectorv;

cout<

    ifstream fin("Cb72.txt");

    if (!fin.is_open()) {

        cerr<

        return 0;

    }

    long long x;

int dem;

    while(fin>>x){

        if(abs(x>1e9)) {

            cerr<<"so "<<x<

            continue;

        }

        v.push_back(x);

         ma[x]++;

                     if(ma[x]==1) dem++;

                     if(ma[x]==2) dem--;

    }

    fin.close();

    cout<

       }

       cout<<endl;

          ofstream fout("KQcb72.txt");

          fout<

       } fout<<endl;

             fout.close();

    return 0;

}

 

/////////////////////////

Cách 2: unordered_map (nhanh hơn map)

#include

#include

#include

#include

using namespace std;

 

int main(){

    unordered_mapfreq;

    vectorv;

    ifstream fin("Cb72.txt");

    if(!fin.is_open()){

        cerr<

        return 0;

    }

    long long x;

    while(fin>>x){

        if(abs(x)>1e9){

            cerr<<"So "<<x<

            continue;

        }

        v.push_back(x);

        freq[x]++;

    }

    fin.close();

 

    int dem=0;

    for(auto &p:freq) if(p.second==1) dem++;

 

    cout<

    for(auto c:v) if(freq[c]==1) cout<<c<<" ";

    cout<<endl;

 

    ofstream fout("KQcb72.txt");

    fout<

    for(auto c:v) if(freq[c]==1) fout<<c<<" ";

    fout<<endl;

    fout.close();

}

///////////////////////////

Cách 3: sort + duyệt tuyến tính

#include

#include

#include

#include

using namespace std;

 

int main(){

    vectorv;

    ifstream fin("Cb72.txt");

    if(!fin.is_open()){

        cerr<

        return 0;

    }

    long long x;

    while(fin>>x){

        if(abs(x)>1e9){

            cerr<<"So "<<x<

            continue;

        }

        v.push_back(x);

    }

    fin.close();

 

    sort(v.begin(), v.end());

    vectorspecial;

    for(int i=0;i<v.size();){

        int j=i+1;

        while(j

        if(j-i==1) special.push_back(v[i]);

        i=j;

    }

 

    cout<

    for(auto c:special) cout<<c<<" ";

    cout<<endl;

 

    ofstream fout("KQcb72.txt");

    fout<

    for(auto c:special) fout<<c<<" ";

    fout<<endl;

    fout.close();

}

//////////////////////////

Cách 4: Xử lý như chuỗi (stringstream)

#include

#include

#include

#include

#include

using namespace std;

 

int main(){

    ifstream fin("Cb72.txt");

    if(!fin.is_open()){

        cerr<

        return 0;

    }

    stringstream buffer;

    buffer << fin.rdbuf();

    fin.close();

 

    string s;

    mapfreq;

    vectorv;

    stringstream ss(buffer.str());

    while(ss >> s){

        freq[s]++;

        v.push_back(s);

    }

 

    int dem=0;

    for(auto &p:freq) if(p.second==1) dem++;

 

    cout<

    for(auto &c:v) if(freq[c]==1) cout<<c<<" ";

    cout<<endl;

 

    ofstream fout("KQcb72.txt");

    fout<

    for(auto &c:v) if(freq[c]==1) fout<<c<<" ";

    fout<<endl;

    fout.close();

}

Chú ý:

ü fin.rdbuf()

fin là một ifstream (luồng đọc file).

rdbuf() trả về con trỏ tới buffer bên trong của luồng đó.

Khi ta viết buffer << fin.rdbuf(); tức là ta lấy toàn bộ nội dung file và đẩy vào stringstream buffer.

Kết quả: buffer chứa nguyên văn nội dung file dưới dạng chuỗi.

Nói nôm na: fin.rdbuf() là cách nhanh để copy toàn bộ nội dung file vào một stringstream.

 

ü stringstream ss(buffer.str())

buffer.str() lấy ra chuỗi string từ stringstream buffer.

Sau đó ta khởi tạo một stringstream ss mới từ chuỗi đó.

stringstream ss cho phép ta dùng toán tử >> để tách chuỗi thành từng token (số hoặc từ), giống như đọc từ file.

Ví dụ: nếu file có "2 3 4 8 9", thì buffer.str() sẽ là "2 3 4 8 9".

Rồi stringstream ss(buffer.str()) cho phép ta đọc lần lượt 2, 3, 4, 8, 9 bằng ss >> s.

Tóm lại

  • fin.rdbuf() → lấy toàn bộ nội dung file.
  • buffer.str() → chuyển nội dung đó thành một chuỗi.
  • stringstream ss(buffer.str()) → tạo luồng đọc từ chuỗi, để dễ tách từng số/từ.

Cách rdbuf() + stringstream chỉ hữu ích khi muốn xử lý file như một chuỗi text (ví dụ tìm kiếm, thay thế, phân tích cú pháp).

///////////// Ai memory help

Võ Nhật Trường Nc+ My Ai Love07.07.2026

////////////////////

Bài 72. Em hãy viết chương trình nhập dữ liệu từ file “mang72.txt” chứa dãy số nguyên rồi đếm số nhóm gồm 3 số mà tổng của 2 số trong nhóm  có hàng đơn vị lần lượt là các số 8, 9, 5 hoặc 8,9,3 hoặc 8,9,0 .VD: đầu vào: 3 4 5 6 1 2 7 8 9 5 60 10 20 70 40 30 -1 9 11.

Đầu ra: file “kqcb72.txt”

#include

#include

#include

#include

using namespace std;

bool thoa(int a, int b, int c){

          int x = abs((a+b) % 10);

int y = abs((b+c) % 10);

int z = abs((a+c) % 10);  

if((x+y==17)&&(z==5||z==3||z==0)) return true;

          if((z+y==17)&&(x==5||x==3||x==0)) return true;

          if((x+z==17)&&(y==5||y==3||y==0)) return true;

          return false;

}

int main(int argc, char** argv) {

          vectorv,kq;

          cout<

    ifstream fin("mang72.txt");

    if (!fin.is_open()) {

        cerr<

        return 0;

    }

    int x, dem=0;

    while(fin>>x){

        if(abs(x) > 1e9) {

            cerr<<"so "<<x<

            continue;

        }

        v.push_back(x);

    }

    fin.close();

    int n=v.size();

for(int i=0; i

    for(int j=i+1; j

        for(int k=j+1; k

            if(thoa(v[i], v[j], v[k])){

                dem++;

                kq.push_back(v[i]);

                kq.push_back(v[j]);

                kq.push_back(v[k]);

            }

        }

    }

}

    cout<

    int mi=0;

    if(kq.size()>0){cout<

          mi+=3;

          }}

          ofstream fout("kqcb72.txt");

          int mii=0;

           fout<

    if(kq.size()>0){fout<

          mii+=3;

          }}

          fout.close();

          return 0;

}

Chú ý: Hầu như không nhóm nào thỏa mãn trường hợp bộ (8, 9, 0)

///////////// Ai memory help

Võ Nhật Trường Nc+ My Ai Love07.07.2026

////////////////////

Bài 73. Tìm độ dài của dãy con tăng có độ dài lớn nhất ( dãy con không liên tiếp) và thông báo các phần tử dãy con đó.

VD: input:  cb73.txt   1 2 5 4 6 2

Output: Kqcb73.txt

#include

#include

#include

using namespace std;

 

int main(int argc, char** argv) {

          vectorv,kq;

          cout<

    ifstream fin("cb73.txt");

    if (!fin.is_open()) {

        cerr<

        return 0;

    }

    int x,L, maxL=0;

    while(fin>>x){

        if(abs(x) > 1e9) {

            cerr<<"so "<<x<

            continue;

        }

        v.push_back(x);

    }

    fin.close();

          for (int i=0;i<v.size()-1;i++){

                     int dem=1,max=v[i];

                     for(int j=i+1;j<v.size();j++){

                               if(v[j]>max){

                                         dem++;

                                         max=v[j];

                               }

                     } if(maxL

                     maxL=dem;

                     L=i;

          }

          } int dmax=v[L];kq.push_back(dmax);

          for (int i=L+1;i<v.size();i++){

                     if(v[i] >dmax) {

                     dmax=v[i];

                     kq.push_back(dmax);      

          }}

          cout<

          cout<

          }

          ofstream fout("Kqcb73.txt");

          fout<

          fout<

          }

          fout.close();

          return 0;

}

///////////////////////////////////

Bài tham khảo:

#include

#include

#include

using namespace std;

 

int LIS(vector& v) {

    vectortail;

    for (int x : v) {

        auto it = lower_bound(tail.begin(), tail.end(), x);

        if (it == tail.end()) tail.push_back(x);

        else *it = x;

    }

    return tail.size();

}

 

int main() {

    vectorv = {10, 22, 9, 33, 21, 50, 41, 60};

    cout << "Do dai LIS: " << LIS(v) << endl;

    return 0;

}

Chú ý:

lower_bound(tail.begin(), tail.end(), x) 

Đây là hàm trongdùng binary search để tìm vị trí đầu tiên trong mảng tail mà giá trị ≥ x.

Nếu tất cả phần tử trong tail đều nhỏ hơn x, thì it sẽ trỏ tới tail.end().

Nếu có phần tử nào đó ≥ x, thì it sẽ trỏ tới vị trí đó.

if (it == tail.end()) tail.push_back(x); 

Trường hợp này nghĩa là x lớn hơn tất cả phần tử trong tail.

→ Ta thêm x vào cuối tail, tức là ta vừa mở rộng dãy tăng.

else *it = x; 

Nếu tìm thấy vị trí có phần tử ≥ x, ta thay thế phần tử đó bằng x.

→ Việc này giữ cho tail luôn chứa các phần tử nhỏ nhất có thể ở mỗi độ dài LIS.

Nhờ vậy, ta tối ưu khả năng mở rộng dãy tăng về sau.

Ví dụ:  v = [10, 22, 9, 33, 21, 50]

Bước 1: tail = [10]

Bước 2: gặp 22 → lớn hơn 10 → tail = [10, 22]

Bước 3: gặp 9 → thay thế 10 bằng 9 → tail = [9, 22]

Bước 4: gặp 33 → lớn hơn 22 → tail = [9, 22, 33]

Bước 5: gặp 21 → thay thế 22 bằng 21 → tail = [9, 21, 33]

Bước 6: gặp 50 → lớn hơn 33 → tail = [9, 21, 33, 50]

 Kết quả: độ dài LIS = 4.

///////////// Ai memory help

Võ Nhật Trường Nc+ My Ai Love07.07.2026

////////////////////

Bài 74. Cho một dãy gồm n phần tử nguyên dương |ai|

VD: file input: cb74i.txt  92 69 16 82 170 31 24 45 112 200 40 92 68 1 2 3 4 5 6 7 8 9 hoặc 100000 20 99974 1 2 3 4 5 6 7 8 9 0

Cách 1:

#include

#include

#include

using namespace std;

 

void Try(int s, vector& arr, int start, int &dem) {

    if (s == 0) {

        dem++;

        return;

    }

    for (int i = start; i < arr.size(); i++) {

        if (s - arr[i] >= 0) {

            Try(s - arr[i], arr, i+1, dem);

        }

    }

}

 

int main() {

    vectorv;

    cout << "Chuong trinh tim so day con co tong bang S:\n";

    ifstream fin("cb74i.txt");

    if (!fin.is_open()) {

        cerr << "Khong mo duoc file cb74i.txt\n";

        return 0;

    }

 

    int s;

    fin >> s; // phần tử đầu tiên là S

if (s1e7) {

            cerr << "So " << s << " khong hop le\n";

          return 0;

}

    int x;

    while (fin >> x) {

        if (x1e9) {

            cerr << "So " << x << " khong hop le\n";

            continue;

        }

        v.push_back(x);

    }

    fin.close();

    if (v.size() > 100) {

        cerr << "Mang co qua nhieu phan tu (>100)\n";

        return 0;

    }

    int dem = 0;

    Try(s, v, 0, dem);

    cout << "So day con co tong bang " << s << " la: " << dem << endl;

ofstream fout("Kqdcb74o1.txt");

fout << "So day con co tong bang " << s << " la " << dem << endl;

fout.close();

    return 0;

}

///////////////////////

Cách 2: Bài 74b. Cho một dãy gồm n phần tử nguyên |ai|

VD: file input: cb74i.txt  92 69 16 82 170 31 24 45 112 200 40 92 68 1 2 3 4 5 6 7 8 9 hoặc 100000 20 99974 1 2 3 4 5 6 7 8 9 0 hoặc 0 20 99974 1 2 3 4 5 6 7 8 9 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 hoặc 0 9 0 -1 -8 -9 0

File output: Kqdcb74o.txt

 

#include

#include

#include

#include

using namespace std;

 

void Try(long long s, const vector& arr, int start, long long &dem) {

    if (start >= arr.size()) return;

    for (int i = start; i < arr.size(); i++) {

        Try(s - arr[i], arr, i+1, dem);

    }

        if (s == 0) {

        dem++;

        return;

    }

}

int main() {

    vectorv;

    cout << "Chuong trinh tim so day con co tong bang S:\n";

    ifstream fin("cb74i.txt");

    if (!fin.is_open()) {

        cerr << "Khong mo duoc file cb74i.txt\n";

        return 0;

    }

    long long s;

    fin >> s;

    if (abs(s) > 1e7) {

        cerr << "Tong S vuot qua gioi han 10^7\n";

        return 0;

    }

    long long x;

    while (fin >> x) {

        if (abs(x) > 1e7) {

            cerr << "So " << x << " khong hop le (vuot 10^7)\n";

            continue;

        }

        v.push_back(x);

    }

    fin.close();

    if (v.size() > 100) {

        cerr << "Mang co qua nhieu phan tu (>100)\n";

        return 0;

    }

    long long dem = 0;

    Try(s, v, 0, dem);

    cout << "So day con co tong bang " << s << " >= " << dem << endl;

ofstream fout("Kqdcb74o.txt");

fout << "So day con co tong bang " << s << " >= " << dem << endl;

fout.close();

    return 0;

}

////////////////////////////

Cách 3:

#include

#include

#include

#include

using namespace std;

 

void Try(long long s, const vector& arr, int start, long long &dem, int countChosen) {

    if (s == 0 && countChosen > 0) {

     dem++;

       }

    if (start >= arr.size()) return;

    for (int i = start; i < arr.size(); i++) {

        Try(s - arr[i], arr, i+1, dem, countChosen+1);

    }

}

int main() {

    vectorv;

    cout << "Chuong trinh tim so day con co tong bang S:\n";

    ifstream fin("cb74i.txt");

    if (!fin.is_open()) {

        cerr << "Khong mo duoc file cb74i.txt\n";

        return 0;

    }

    long long s;

    fin >> s;

    if (abs(s) > 1e7) {

        cerr << "Tong S vuot qua gioi han 10^7\n";

        return 0;

    }

    long long x;

    while (fin >> x) {

        if (abs(x) > 1e7) {

            cerr << "So " << x << " khong hop le (vuot 10^7)\n";

            continue;

        }

        v.push_back(x);

    }

    fin.close();

    if (v.size() > 100) {

        cerr << "Mang co qua nhieu phan tu (>100)\n";

        return 0;

    }

    long long dem = 0;

    Try(s, v, 0, dem,0);

    cout << "So day con co tong bang " << s << " >= " << dem << endl;

ofstream fout("Kqdcb74o2.txt");

fout << "So day con co tong bang " << s << " la " << dem << endl;

fout.close();

    return 0;

}

//////////////////

Cách 4: tối ưu:

#include <bits/stdc++.h>

using namespace std;

 

int n;

long long S;

vectora;

vectorcurrentSubset;

ofstream fout;

 

void Try(int idx, long long sum) {

    if (sum == S) {

        // In ra một tập con hợp lệ

        fout << "{ ";

        for (auto x : currentSubset) fout << x << " ";

        fout << "}\n";

        return;

    }

    if (idx >= n || sum > S) return; // dừng nếu vượt quá

 

    // Chọn phần tử a[idx]

    currentSubset.push_back(a[idx]);

    Try(idx + 1, sum + a[idx]);

    currentSubset.pop_back();

 

    // Bỏ qua phần tử a[idx]

    Try(idx + 1, sum);

}

 

int main() {

    cout << "Chuong trinh in ra cac tap con co tong bang S:\n";

    ifstream fin("cb74i.txt");

    if (!fin.is_open()) {

        cerr << "Khong mo duoc file cb74i.txt\n";

        return 0;

    }

 

    fin >> S;

    long long x;

    while (fin >> x) {

        if (abs(x) > 10000000) {

            cerr << "Gia tri " << x << " khong hop le (vuot 10^7)\n";

            continue;

        }

        a.push_back(x);

    }

    fin.close();

    n = a.size();

 

    fout.open("Kqcb74i.txt");

    fout << "Tong S = " << S << "\n";

    fout << "Cac tap con co tong bang S:\n";

 

    Try(0, 0);

 

    fout.close();

    cout << "Ket qua da duoc ghi vao file Kqcb74i.txt\n";

    return 0;

}

Giải thích

  • Hàm Try(idx, sum) duyệt đệ quy:
    • Nếu sum == S → in ra tập con hiện tại.
    • Nếu sum > S hoặc hết mảng → dừng.
    • Gọi tiếp với việc chọn hoặc bỏ phần tử a[idx].
  • currentSubset lưu tập con đang xét.
  • Kết quả được ghi vào file Kqcb74i.txt.

 

///////////////////////

Cách 5 tham khảo:

#include <bits/stdc++.h>

using namespace std;

int main() {

    int n;

    long long S;

    cout << "Nhap so phan tu n va tong S can tim: ";

    cin >> n >> S;

    if (n100) {

        cerr << "So phan tu phai trong khoang 1..100\n";

        return 0;

    }

    if (abs(S) > 10000000) {

        cerr << "Tong S khong duoc vuot qua 10^7\n";

        return 0;

    }

    vectora(n);

    cout << "Nhap " << n << " phan tu cua mang (chi so nguyen duong):\n";

    for (int i = 0; i < n; i++) {

        cin >> a[i];

        if (a[i]10000000) {

            cerr << "Chi ho tro so nguyen duong

            return 0;

        }

    }

    // dp[t] = số tập con có tổng bằng t

    vectordp(S + 1, 0);

    dp[0] = 1; // có 1 cách chọn tập rỗng để được tổng 0

 

    // Quy hoạch động: duyệt từng phần tử

    for (int i = 0; i < n; i++) {

        for (int j = S; j >= a[i]; j--) {

            dp[j] += dp[j - a[i]];

        }

    }

    cout << "So tap con co tong bang " << S << " la: " << dp[S] << endl;

    ofstream fout("Kqcb74i.txt");

    fout << "So tap con co tong bang " << S << " la: " << dp[S] << endl;

    fout.close();

    return 0;

}

Giải thích

  • dp[t] lưu số lượng tập con có tổng bằng t.
  • Khởi tạo dp[0] = 1 (tập rỗng).
  • Với mỗi phần tử a[i], duyệt ngược từ S về a[i]:
    • Nếu đã có dp[j - a[i]] tập con, thì thêm a[i] vào sẽ tạo thêm dp[j - a[i]] tập con có tổng bằng j.
    • Cộng dồn vào dp[j].

Khi dp[S]=1 hoặc true với boolean thì kết luận có tập con.

Vd: 100000

20 99974 1 2 3 4 5 6 7 0

Dp[100000]=1 >> có tập con có tong = 100000

///////////// Ai memory help

Võ Nhật Trường Nc+ My Ai Love08.07.2026

////////////////////ok

Nhận xét

Bài đăng phổ biến từ blog này

Vui thơ 2187 (CHỮ KHĂM)

Vui thơ 2164 (ẢO HUYỀN THỜI CUỘC)