Một số bài C_C++ Nhật Trường NC PC22

 











BÀI 57. Cho số nguyên dương n. (n<= 10 12 ). Hãy đưa ra chữ số lớn nhất của n.

Cách 1: Dùng toán học (chia lấy dư)

#include <bits/stdc++.h>

using namespace std;

 

int main() {

    long long n;

    cout << "Nhap so nguyen duong n: ";

    cin >> n;

 

    if (n <= 0 || n > 1000000000000) {

        cout << "So khong hop le";

        return 0;

    }

    long long maxDigit = 0;

    while (n != 0) {

        long long digit = n % 10;   // lấy chữ số cuối

        n = n / 10;                 // bỏ chữ số cuối

        if (digit > maxDigit)       // cập nhật chữ số lớn nhất

            maxDigit = digit;

    }

    cout << "Chu so lon nhat la: " << maxDigit;

    return 0;

}

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

Cách 2:

#include <bits/stdc++.h>

using namespace std;

 

int main() {

    long long n;

    cout << "Nhap so nguyen duong n: ";

    cin >> n;

 

    if (n <= 0 || n > 1000000000000) {

        cout << "So khong hop le";

        return 0;

    }

    string s = to_string(n);   // chuyển số sang chuỗi

    char maxChar = '0';

 

    for (char c : s) {

        if (c > maxChar)       // so sánh ký tự

            maxChar = c;

    }

 

    cout << (maxChar - '0');   // chuyển ký tự về số

    return 0;

}

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

#include <bits/stdc++.h>

using namespace std;

 

int main() {

    long long n;

    cout << "Nhap so nguyen duong n: ";

    cin >> n;

    // Bẫy lỗi: kiểm tra n hợp lệ

    if (n <= 0 || n > 1000000000000) {

        cout << "So khong hop le!";

        return 0;

    }

    string s = to_string(n);

    string a = s.substr(0,1); // khởi tạo bằng chữ số đầu tiên

    // duyệt từ chữ số thứ 2 trở đi

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

        if (s.substr(i,1) > a)

            a = s.substr(i,1);

    }

    int maxDigit = stoi(a);

    cout << "Chu so lon nhat la: " << maxDigit;

    return 0;

}

Khởi tạo: bắt đầu với chữ số đầu tiên s.substr(0,1) thay vì gán cứng "1", để tránh sai khi số nhỏ hơn 1.

ü    1e12 nghĩa là .

ü    10e11 cũng bằng .

if (n <= 0 || n > 1e12) {

    cout << "So khong hop le!";

    return 0;

}

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

BÀI 58. Cho số nguyên dương n. Hãy đếm xem n có bao nhiêu chữ số và tổng các chữ số của n.

#include <iostream>

#include <fstream>

#include <string>

using namespace std;

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

          cout<<"Ban hay nhap so nguyen duong n";

          int n;

          cin>>n;

          if (n<=0||n>3e4) {

          cout<<"so khong hop le";

          return 0;

}

          string s=to_string(n);

          int dem=s.size();

          cout<<" so chu so trong n la:"<<dem;

          ofstream fout("kqdem.txt");

          fout<<" so chu so trong "<<n<<" la:"<<dem;

          fout.close();

          return 0;

}

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

BÀI 59. Cho số n nguyên dương. Hãy in ra số lớn nhất trong các chữ số của n.

Ví dụ: 256790 in ra 976520

#include <iostream>

using namespace std;

string sortg(string sg){

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

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

                     if(sg[i]<sg[j]) swap(sg[i],sg[j]);

          } return sg; 

};

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

          cout<<"Ban hay nhap mot so nguyen duong: ";

          string s;

          cin>>s;

          for (char c:s) {

                     if(!isdigit(c)) {

                     cerr<<"Loi nhap du lieu dau vao";

                     return 0;

          }

}        string smax=sortg(s);

          cout<<"so ban nhap la: "<<s<<endl;

          cout<<"So lon nhat trong cac chu so da nhap la: "<<smax<<endl;

          return 0;

}

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

Cách 2:

#include <bits/stdc++.h>

using namespace std;

int main() {

    cout << "Ban hay nhap mot so nguyen duong: ";

    string s;

    cin >> s;

    for (char c : s) {

        if (!isdigit(c)) {

            cerr << "Loi nhap du lieu dau vao!";

            return 0;

        }

    }

          string si=s;

    sort(si.begin(), si.end(), greater<char>());

    cout<<"so ban nhap la: "<<s<<endl;

          cout<<"So lon nhat trong cac chu so da nhap la: "<<si<<endl;

    cout << "Chu so lon nhat trong cac chu so da nhap la: " << si[0] << endl;

    return 0;

}

Chú ý: sort(si.begin(), si.end(), greater<char>());

Sắp xếp chuỗi giảm dần và không có giá trị trả về.

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

Có thể sử dụng lệnh sort trong C++ cho mảng số lẫn xâu ký tự

Ví dụ:

#include <bits/stdc++.h>

using namespace std;

 

int main() {

    // Ví dụ với mảng số

    int arr[] = {5, 2, 9, 1, 7};

    int n = sizeof(arr)/sizeof(arr[0]);

 

    sort(arr, arr+n); // sắp xếp tăng dần

 

    cout << "Mang sau khi sort: ";

    for (int i=0; i<n; i++) cout << arr[i] << " ";

    cout << endl;

 

    // Ví dụ với xâu ký tự

    string s = "copilot";

    sort(s.begin(), s.end()); // sắp xếp các ký tự theo thứ tự ASCII

    cout << "Xau sau khi sort: " << s << endl;

    return 0;

}

Kết quả

  • Mảng số: 1 2 5 7 9
  • Xâu "copilot" sau khi sort thành "cilooprt" (theo thứ tự chữ cái ASCII).

Ghi nhớ

  • sort(arr, arr+n) dùng cho mảng.
  • sort(s.begin(), s.end()) dùng cho string hoặc vector.
  • Nếu muốn sắp xếp giảm dần, thêm greater<>():

sort(arr, arr+n, greater<int>());

sort(s.begin(), s.end(), greater<char>());

 

trong C++ có cách gọn hơn: dùng hàm so sánh ngay trong sort.

Ví dụ với mảng số:

#include <bits/stdc++.h>

using namespace std;

 

int main() {

    int arr[] = {5, 2, 9, 1, 7};

    int n = sizeof(arr)/sizeof(arr[0]);

    // Sắp xếp giảm dần trực tiếp

    sort(arr, arr+n, greater<int>());

    cout << "Mang sau khi sort giam dan: ";

    for (int i=0; i<n; i++) cout << arr[i] << " ";

    return 0;

}

Ví dụ với xâu ký tự

#include <bits/stdc++.h>

using namespace std;

 

int main() {

    string s = "copilot";

    // Sắp xếp giảm dần ký tự

    sort(s.begin(), s.end(), greater<char>());

    cout << "Xau sau khi sort giam dan: " << s;

    return 0;

}

Nhận xét

Nếu dùng sort(arr, arr+n) hoặc sort(s.begin(), s.end()) thì mặc định là tăng dần.

Nếu muốn giảm dần, chỉ cần thêm greater<>() là xong, không cần đảo ngược nữa.

Tuy nhiên, nếu đã sort tăng dần rồi đảo ngược bằng reverse(...) thì cũng đúng, chỉ là thêm một bước phụ.

Với mảng tĩnh (ví dụ int arr[5] = {1,2,3,4,5};), Muốn lấy số phần tử thì phải dùng công thức:

int n = sizeof(arr) / sizeof(arr[0]);

sizeof(arr) cho tổng số byte của cả mảng.

sizeof(arr[0]) cho số byte của một phần tử.

Chia hai giá trị này sẽ ra số phần tử.

Với container động trong STL (như vector, string, array trong <array>), ta có thể dùng trực tiếp .size(). Ví dụ:

vector<int> v = {1,2,3,4,5};

cout << v.size(); // in ra 5

Tóm lại:

Mảng tĩnh → dùng sizeof(arr)/sizeof(arr[0]).

Container STL (vector, string, array) → dùng .size().

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

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

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

BÀI 60. Cho file bcb60.txt chứa các số nguyên . Hãy đưa ra số lượng của dãy con có tổng các phần tử lớn hơn hoặc bng S. Hãy đưa ra Độ dài của dãy con liên tiếp nhỏ nhất và lớn nhất có tổng lớn hơn hoặc bằng S. Chú ý số đầu tiên trong file là S, các số tiếp theo là số nguyên. Vd: input.txt  10 4 -25 30 5 -15 0 0 24 -9 12

Gợi ý cách 1:

#include <iostream>

#include <vector>

#include <fstream>

using namespace std;

 

bool tonghl(vector<int> v, int n, int m){

    int sz = v.size() - 1;

    if (sz < 1 || n < 1 || n > m || m > sz) return false;

    int sumd = 0;

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

        sumd += v[i];

    } if(sumd >= v[0])cout<<n<< ">>"<< m<< "Tong "<< sumd<<endl;

    return sumd >= v[0];

}

 

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

    ifstream fin("input.txt");

    vector<int> arr;

    int x;

    while(fin >> x){

        arr.push_back(x);

    }

    int n = arr.size() - 1;

    int dem = 0, min = n+1, max = 0;

 

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

        if (arr[i] > arr[0]) {

            dem++;

            cout<<i<<"  tong"<< arr[i]<<endl;

            min = 1;

            if (max < 1) max = 1;

        }

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

                if (tonghl(arr,i,j)) {

                    dem++;

                    if (min > (j-i+1)) min = j-i+1;

                    if (max < (j-i+1)) max = j-i+1;

                }

            }

        }

    if (max < min) max = min;

 

    cout << "so luong day con co tong >=" << arr[0] << " la: " << dem << endl;

    cout << "day con co do dai nho nhat la: " << min << endl;

    cout << "day con co do dai lon nhat la: " << max << endl;

 

    ofstream fout("kqcb60.txt");

    fout << "so luong day con co tong >=" << arr[0] << " la: " << dem << endl;

    fout << "day con co do dai nho nhat la: " << min << endl;

    fout << "day con co do dai lon nhat la: " << max << endl;

    return 0;

}

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

Cách 2:

#include <iostream>

#include <vector>

#include <fstream>

#include <climits>

using namespace std;

 

int main() {

    ifstream fin("input.txt");

    int S;

    fin >> S; // s? d?u tiên là ngu?ng S

    vector<int> arr;

    int x;

    while(fin >> x) arr.push_back(x); // các s? còn l?i là m?ng

    int n = arr.size();

 

    // prefix sum

    vector<long long> prefix(n+1,0);

    for(int i=1;i<=n;i++) prefix[i]=prefix[i-1]+arr[i-1];

 

    int dem=0, minLen=INT_MAX, maxLen=0;

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

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

            long long sum = prefix[j]-prefix[i];

            if(sum>=S){

                     cout << "Doan [" << i << "," << j-1 << "] sum=" << sum << endl;

                dem++;

                int len = j - i; // d? dài dúng là j-i

                if(len < minLen) minLen = len;

                if(len > maxLen) maxLen = len;

            }

        }

    }

    if(minLen==INT_MAX) minLen=0; // không có dãy nào

 

cout<<"So luong day con co tong >= "<<S<<" la: "<<dem<<endl;

cout<<"Do dai nho nhat: "<<minLen<<endl;

cout<<"Do dai lon nhat: "<<maxLen<<endl;

 

ofstream fout("kqcb60b.txt");

fout<<"So luong day con co tong >= "<<S<<" la: "<<dem<<endl;

fout<<"Do dai nho nhat: "<<minLen<<endl;

fout<<"Do dai lon nhat: "<<maxLen<<endl;

}

Chú ý:

vector<long long> prefix(n+1,0); đúng là tạo mảng có n+1 phần tử, tất cả khởi tạo bằng 0. Đây là cách chuẩn để làm mảng tổng tích lũy.

  • prefix có n+1 phần tử, prefix[0]=0.
  • Tổng đoạn [i..j-1] (theo chỉ số trong arr) = prefix[j] - prefix[i].
  • Độ dài đoạn = j - i. vì phần tử được tính từ 1, prefix[0]=0 mac dinh;
  • arr.size() tự động cho biết số phần tử của mảng, không liên quan đến S.

 

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

BÀI 61. Nhập vào một số nguyên n. Hãy đưa ra ước số nguyên tố lớn nhất của n.

Gợi ý:

#include <bits/stdc++.h>

using namespace std;

 

int main() {

    int n;

    // Nhập số nguyên dương n từ bàn phím

    cout << "Nhap n: ";

    cin >> n;

    if (n<=0||n>2e9){

          cout<<" So nhap loi";

          return 0;

    }

    int res = -1; // biến lưu ước số nguyên tố lớn nhất

    // Duyệt từ 2 đến n, chia dần n cho các ước số nguyên tố

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

        while (n % i == 0) {

            res = i;   // cập nhật ước số nguyên tố hiện tại

            n = n / i; // giảm n dần

        }

    }

    // Xuất kết quả ra màn hình

    cout << "Uoc so nguyen to lon nhat la: " << res << endl;

    return 0;

}

Chú ý:

Trong C++ thì:

  • INT_MAX là hằng số được định nghĩa trong <climits> (hoặc <limits.h>), biểu diễn giá trị lớn nhất có thể lưu trong kiểu int.
  • Tương tự, còn có INT_MIN là giá trị nhỏ nhất của int.
  • Nếu bạn dùng long long thì có LLONG_MAX, LLONG_MIN.

Ví dụ minh họa:

#include <iostream>

#include <climits> // để dùng INT_MAX, INT_MIN

using namespace std;

 

int main() {

    cout << "Gia tri lon nhat cua int: " << INT_MAX << endl;

    cout << "Gia tri nho nhat cua int: " << INT_MIN << endl;

    cout << "Gia tri lon nhat cua long long: " << LLONG_MAX << endl;

    cout << "Gia tri nho nhat cua long long: " << LLONG_MIN << endl;

    return 0;

}

Kết quả (trên hệ thống 32-bit hoặc 64-bit phổ biến):

Gia tri lon nhat cua int: 2147483647

Gia tri nho nhat cua int: -2147483648

Gia tri lon nhat cua long long: 9223372036854775807

Gia tri nho nhat cua long long: -9223372036854775808

INT_MAX trong C++ thường có giá trị 2,147,483,647 (tức khoảng ), còn INT_MIN là -2,147,483,648. Vì vậy bạn có thể hình dung nó tương đương với khoảng ±2e9.

  • Với kiểu int (thường 32-bit): phạm vi là từ đến .
  • Với kiểu long long (thường 64-bit): phạm vi rộng hơn nhiều, từ đến .

 

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

Cách 2:

#include <bits/stdc++.h>

using namespace std;

 

int main() {

    long long n;

    cout << "Nhap n: ";

    cin >> n;

    long long res = -1;

    // Chia hết cho 2 trước

    while (n % 2 == 0) {

        res = 2;

        n /= 2;

    }

    // Duyệt các số lẻ từ 3 đến sqrt(n)

    for (long long i = 3; i * i <= n; i += 2) {

        while (n % i == 0) {

            res = i;

            n /= i;

        }

    }

    // Nếu sau cùng n > 1 thì n là số nguyên tố lớn nhất

    if (n > 1) res = n;

    cout << "Uoc so nguyen to lon nhat la: " << res << endl;

    return 0;

}

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

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

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

BÀI 62. Cho một mảng gồm các phần tử là số nguyên dương. Hãy đưa phần tử lẻ lớn nhất và vị trí của số đó trong mảng. Input: bai62.inp

 

Input

Output

10

2 3 4 5 8 9 4 11 2 3

11 8

 

#include <bits/stdc++.h>

using namespace std;

int a[10002];

int n;

int ptmax;

int vt=0;

int le;

int main(){

    freopen("bai62.inp","r",stdin);

  

    cin>>n;

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

        cin>>a[i];

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

        if(a[i]%2==1) le=a[i];

        if(ptmax< le){

        ptmax=le;

        vt=i+1;

    }

    }cout << ptmax << " "<<vt<< endl;

    freopen("bai62.out","w",stdout);

        cout << ptmax << " "<<vt<< endl;

    return 0;

}

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

BÀI 63. Chuyển xâu chữ hỗn hợp (hoa, thường, số, ..) thành xâu chữ thường có chứa dấu cách, số. File input: xauchu.txt.

Gợi ý code:

#include <bits/stdc++.h>

#include <string>

using namespace std;

string chuyenhoathanhthuong(string s){

          string sti="";

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

        if(s[i]>='A'&&s[i]<='Z') {

                     s[i]+=32;

      } sti+=s[i];}

      return sti;

}

int main(){

          cout << "Ban hay cung cap file dau vao xauchu.txt\n";

    freopen("xauchu.txt","r",stdin);

    string s="", line;

    while(getline(cin,line)){

          s+=line+"\n";

          }

          string st="";

          st=chuyenhoathanhthuong(s);

          cout<<"xau chu da nhap la: \n"<<s<<endl;

    cout<<"xau chu hoa thanh thuong la: \n"<<st<<endl;

    freopen("kqout.txt","w",stdout);

    cout<<"xau chu da nhap la: \n"<<s<<endl;

    cout<<"xau chu hoa thanh thuong la: \n"<<st<<endl;

    return 0;

}

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

BÀI 64. Chuyển xâu chữ hỗn hợp (hoa, thường, số, ..) thành xâu chữ hoa có chứa dấu cách, số. File input: xauchu.txt.

#include <bits/stdc++.h>

#include <string>

using namespace std;

string chuyenxauchuhoa(string s){

          string sti="";

      for(char c:s){

        if(c>='a'&&c<='z') {

                     c-=32;

      } sti+=c;}

      return sti;

}

int main(){

          cout << "Ban hay cung cap file dau vao xauchu.txt\n";

    freopen("xauchu.txt","r",stdin);

    string s="", line;

    while(getline(cin,line)){

          s+=line+"\n";

          }

          string st="";

          st= chuyenxauchuhoa (s);

          cout<<"xau chu da nhap la: \n"<<s<<endl;

    cout<<"xau chu chuyen hoa la: \n"<<st<<endl;

    freopen("kqout.txt","w",stdout);

    cout<<"xau chu da nhap la: \n"<<s<<endl;

    cout<<"xau chu chuyen hoa la: \n"<<st<<endl;

    return 0;

}

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

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

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

BÀI 65. Ước thực sự của số tự nhiên N là ước nguyên dương khác 1 và khác chính nó. Hai số được gọi là anh em nếu chúng có tổng các ước thực sự bằng nhau.

Ví dụ: 6 và 25 được gọi là hai số anh em vì các ước thực sự của 6 là 2 và 3 có tổng bằng 5 và các ước thực sự của 25 là 5 có tổng là 5.

Yêu cầu: Viết chương trình để kiểm tra hai số có phải là hai số anh em không?

Dữ liệu vào từ file văn bản BAIcb65.INP: Chỉ gồm một dòng duy nhất chứa hai số nguyên dương M, N (0 < M, N < 104) cách nhau ít nhất một ký tự trống.

Kết quả ghi file văn bản BAIcb65.OUT: So m và n la anh em co tong uoc la: z hoặc  So m và n khong la anh em Ví dụ: 49  10 la anh em co tong uoc la 7

Gợi ý cách 1:

#include <iostream>

using namespace std;

int tonguoc(int n) {

    int tu = 0;

    for (int i = 2; i*i <= n; i++) {

        if (n % i == 0) {

            tu += i;

            if (i != n/i) tu += n/i;

        }

    }

    return tu;

}

 

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

          cout<<"Chuong trinh tim cap so anh em, dat file du lieu vao BAIcb65.INP \n";

          freopen("BAIcb65.INP","r",stdin);

          int m, n;

          cin>>m>>n;

          if (m*n<=0 ||m>2e9||n>2e9) {

          cerr<<"du lieu vao khong hop le";

          return 0; }

          int tn=tonguoc(n);

          int tm=tonguoc(m);

          if(tn==tm&&tn>0)

                     cout<<"So ["<<n<<" va "<<m<<"] la anh em co tong uoc thuc su la: "<<tn<<endl;

          else cout<<"So ["<<n<<" va "<<m<<"] khong la anh em vi co tong uoc lan luot la: "

          <<tn<< " va "<<tm<<endl;       

                     // xuat ket qua file

          freopen("BAIcb65.OUT","w",stdout);

          if(tn==tm)

                     cout<<"So ["<<n<<" va "<<m<<"] la anh em co tong uoc thuc su la: "<<tn<<endl;

          else cout<<"So ["<<n<<" va "<<m<<"] khong la anh em vi co tong uoc lan luot la: "

          <<tn<< " va "<<tm<<endl;       

          return 0;

}

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

Ví dụ: cách phân tích thừa số nguyên tố để tính tổng ước, thì công thức chuẩn là:

Trong đó là thừa số nguyên tố của .

Gợi ý cách 2: tính tổng ước theo phân tích thừa số (bỏ 1 và chính n)

#include <iostream>

using namespace std;

int tonguoc(int n) {

    int sum = 1;

    int temp = n;

    for (int i = 2; i <= temp; i++) {

        if (temp % i == 0) {

            int p = i;

            int k = 0;

            while (temp % i == 0) {

                temp /= i;

                k++;

            }

            // cá»™ng theo công thức hình học

            int si = 0;

            int pow = 1;

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

                si += pow;

                pow *= p;

            }

            sum *= si;

        }

    }

    return sum - n-1;  //bo 1 và n

          }

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

          cout<<"Chuong trinh tim cap so anh em, dat file du lieu vao BAIcb65.INP \n";

          freopen("BAIcb65.INP","r",stdin);

          int m, n;

          cin>>m>>n;

          if (m*n<=0 ||m>2e9||n>2e9) {

          cerr<<"du lieu vao khong hop le";

          return 0; }

          int tn=tonguoc(n);

          int tm=tonguoc(m);

          if(tn==tm&&tn>0)

                     cout<<"So ["<<n<<" va "<<m<<"] la anh em co tong uoc thuc su la: "<<tn<<endl;

          else cout<<"So ["<<n<<" va "<<m<<"] khong la anh em vi co tong uoc lan luot la: "

          <<tn<< " va "<<tm<<endl;       

                     // xuat ket qua file

          freopen("BAIcb65c2.OUT","w",stdout);

          if(tn==tm)

                     cout<<"So ["<<n<<" va "<<m<<"] la anh em co tong uoc thuc su la: "<<tn<<endl;

          else cout<<"So ["<<n<<" va "<<m<<"] khong la anh em vi co tong uoc lan luot la: "

          <<tn<< " va "<<tm<<endl;       

          return 0;

}

Chú ý : si chính xác bằng .

Hoặc Dùng công thức rút gọn:

int si = (int)(pow(p, k+1) - 1) / (p - 1);

sum *= si; //tích tổng ước của mỗi thừa số nguyên tố

 

*Ưu điểm:

  • Không cần duyệt tới n/2.
  • Chạy nhanh kể cả với số lớn.
  • Đúng theo cách phân tích thừa số nguyên tố.

Ví dụ:

  • tonguoc(12) → .
  • tonguoc(18) → .

Giải thích:

1. Phân tích thừa số nguyên tố

Giả sử số được phân tích thành:

trong đó là các số nguyên tố, là số mũ tương ứng.

2. Công thức tổng ước số

Tổng tất cả các ước số của được ký hiệu là . Công thức là:

3. Ý nghĩa công thức

  • Với mỗi thừa số nguyên tố , các ước số liên quan đến nó là:

Tổng của chúng là:

  • Vì các thừa số nguyên tố độc lập, ta nhân các tổng này lại để có tổng tất cả ước số của .

4. Ví dụ minh họa

Lấy .

  • Phân tích: .
  • Áp dụng công thức:

  • Kiểm tra trực tiếp: các ước của 12 là . Tổng = 28. Đúng!

Tóm lại: công thức chỉ đơn giản là nhân các tổng cấp số nhân của từng thừa số nguyên tố trong phân tích của .

Hàm ước số: ngoài tổng ước số , còn có hàm đếm số ước với công thức .

 

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

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

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

BÀI 66. Cho file Input66.txt gồm số nguyên đầu và n số nguyên dương (trừ phần tử đầu). Hãy cho biết có bao nhiêu cặp số a i +a j chia hết cho phần tử đầu file(so nguyen duong)  . Với 1<=i<j<=n. 1<=n<=10 5  và 1<=a i <=10 5  . VD:

Input66.txt  :  3 3 8 6 9  7 12

Output66.txt    3,6   3,9    3,12    8,7  6,9    6,12       9,12

#include <iostream>

#include <vector>

#include <fstream>

using namespace std;

 

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

          cout<<"chuong trinh tim tong chia het cho c \n";

          cout<<"ban thiet dat file Input66.txt  dau vao";

          ifstream fin("Input66.txt");

          ofstream fout("Output66.txt");

          if(!(fin.is_open())) {cerr<<"khong mo duoc file du lieu Input66.txt";

          return 0;}

          int x,z;

          fin>>z;

          if (z<2||z>2e8) {cerr<<"gia tri z khong hop le";

          return 0;}

          vector<int> v;

          while(fin>>x){

                     v.push_back(x);

          }

          int m=v.size()-1;

          fout<<"Ket qua: \n";

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

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

                               if ((v[i]+v[j])%z==0)

                               fout<<v[i]<<" + "<<v[j]<<"  chia het cho "<<z<<endl;

                     }

          }

          return 0;

}

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

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

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

 

 

BÀI 67. Cho file input67.txt chứa số nguyên đầu là số phần tử của mảng và dãy số nguyên tiếp theo là dãy các phần tử mảng a1, a2,..., an. (|ai|<10 7 , n<10 2 ).

Một tập hợp khác rỗng các số hạng liên tiếp(ai, a i+1 ,... ak)(i<=k) gọi là đoạn con của dãy đó. Với mỗi đoạn con ta tính tổng tất cả các số hạng của nó.

 Yêu cầu: tìm giá trị lớn nhất trong số các tổng của các đoạn con của dãy đã cho.

Đầu ra: kqout67.txt

Input

Output

10 1 -2 -1 4 -1 5 -2 80 -200

86

Gợi ý code:

#include <bits/stdc++.h>

using namespace std;

int main() {

    ios::sync_with_stdio(false);

    cin.tie(nullptr);

    ifstream fin("input67.txt");

    if (!fin.is_open()) {

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

        return 1;

    }

    int n;

    fin >> n;

    if (n <= 0 || n >= 100) {

        cerr << "So phan tu khong hop le (0 < n < 100)\n";

        return 1;

    }

    vector<int> a(n+1);

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

        fin >> a[i];

        if (abs(a[i]) >= 10000000) {

            cerr << "Gia tri phan tu vuot qua gioi han |ai| < 10^7\n";

            return 1;

        }

    }

    fin.close();

    // Tính prefix sum

    vector<long long> prefix(n+1, 0);

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

        prefix[i] = prefix[i-1] + a[i];

    }

    long long maxSum = LLONG_MIN;

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

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

            long long sum = prefix[j] - prefix[i-1];

            if (sum > maxSum) maxSum = sum;

        }

    }

    ofstream fout("kqout67.txt");

    if (!fout.is_open()) {

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

        return 1;

    }

    fout << maxSum << "\n";

    fout.close();

    return 0;

}

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

BÀI 67.b Cho file input67.txt chứa số nguyên đầu là số phần tử của mảng và dãy số nguyên tiếp theo là dãy các phần tử mảng a1, a2,..., an. (|ai|<10 7 , n<10 2 ).

Một tập hợp khác rỗng các số hạng liên tiếp từ i đến k (ai,... ak)(1<=i<=k<=n) gọi là đoạn con của dãy đó. Với mỗi đoạn con ta tính tổng tất cả các số hạng của nó.

 Yêu cầu: tìm giá trị lớn nhất trong số các tổng của các đoạn con của dãy đã cho.

Đầu ra: kqout67.txt

#include <bits/stdc++.h>

using namespace std;

 

int main() {

    ios::sync_with_stdio(false);

    cin.tie(nullptr);

 

    // Mở file input

    ifstream fin("input67.txt");

    if (!fin.is_open()) {

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

        return 1;

    }

    int n;

    fin >> n; // giả sử dòng đầu chứa số lượng phần tử

    if (n <= 0 || n > 100) {

        cerr << "So phan tu khong hop le (0 < n < 100)\n";

        return 1;

    }

    vector<int> a(n);

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

        fin >> a[i];

        if (abs(a[i]) >= 10000000) {

            cerr << "Gia tri phan tu vuot qua gioi han |ai| < 10^7\n";

            return 1;

        }

    }

    fin.close();

    // Kadane's algorithm

    long long maxSum = a[0];

    long long currentSum = a[0];

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

        currentSum = max((long long)a[i], currentSum + a[i]);

        maxSum = max(maxSum, currentSum);

    }

    // Ghi kết quả ra file output

    ofstream fout("kqout67.txt");

    if (!fout.is_open()) {

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

        return 1;

    }

    fout << maxSum << "\n";

    fout.close();

    return 0;

}

Điểm hay là chỉ với một vòng lặp, ta đã “nhảy” qua các khả năng và chọn đoạn con tối ưu mà không cần duyệt tất cả cặp chỉ số như cách dùng prefix sum. Đây là lý do Kadane’s algorithm chạy O(n) thay vì O(n²).

Sự kết hợp của hàm max ở đây chính là “trái tim” của thuật toán: nó biến việc duyệt tuyến tính thành một quá trình ra quyết định tối ưu tại mỗi bước.

 

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

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

////////////////////Ok

Nhận xét