Mô tả
Cho một mảng N số nguyên trong đó N là số chẵn. Có hai loại phép toán được phép trên mảng.
- Tăng giá trị của bất kỳ phần tử nào của mảng lên 1.
- Nếu hai phần tử liền kề trong mảng là số nguyên tố liên tiếp, hãy xóa cả hai phần tử đó.
Nhiệm vụ là tìm số lượng phép toán tối thiểu cần thiết để loại bỏ tất cả các phần tử của mảng.
Ví dụ
Nếu mảng là {10, 13} thì bắt buộc phải có 2 phép toán tối thiểu
- Phần tăng 1 st phần tử của một mảng bằng 1. Vì vậy, mảng mới trở thành {11, 13}
- Xóa 1 st và 2 nd phần tử vì cả hai đều là số nguyên tố liên tiếp
Thuật toán
1. To remove numbers, we must transform two numbers to two consecutive primes. 2. Let us suppose a and b are the consecutive prime numbers then we use sieve of Eratosthenes to precompute prime numbers and then find the first prime p not greater than a and the first greater than p using array 3. Once this computation is done use dynamic programming to solve the problem
Ví dụ
#include <iostream> #include <algorithm> #include <queue> using namespace std; int minimumPrefixReversals(int *a, int n) { string start = ""; string destination = "", t, r; for (int i = 0; i < n; i++) { start += to_string(a[i]); } sort(a, a + n); for (int i = 0; i < n; i++) { destination += to_string(a[i]); } queue<pair<string, int> > qu; pair<string, int> p; qu.push(make_pair(start, 0)); if (start == destination) { return 0; } while (!qu.empty()) { p = qu.front(); t = p.first; qu.pop(); for (int j = 2; j <= n; j++) { r = t; reverse(r.begin(), r.begin() + j); if (r == destination) { return p.second + 1; } qu.push(make_pair(r, p.second + 1)); } } } int main() { int a[] = { 1, 2, 4, 3 }; int n = sizeof(a) / sizeof(a[0]); cout << "Minimum reversal: " << minimumPrefixReversals(a, n) << endl; return 0; }
Khi bạn biên dịch và thực thi chương trình trên. Nó tạo ra kết quả sau:
Đầu ra
Minimum reversal: 3