Professional Documents
Culture Documents
04 De-Quy
04 De-Quy
2. Tính ab
long long Pow(int a, int b)
{
if (b == 0) return 1;
return Pow(a, b-1) * a;
}
6. Liệt kê tất cả các tập con 𝑘 phần tử trong 𝑁 phần tử (tổ hợp chập 𝑘 của 𝑁).
void Ghi()
{
for (int i = 1; i <= k; i++) cout << x[i] << " ";
cout << endl;
}
8. Cho một số nguyên dương N. Đưa ra tất cả các cách phân tích N thành tổng các số nguyên
dương khác.
Ví dụ: N = 5. N = 1 + 1 + 1 + 1 + 1 = 1 + 1 + 1 + 2 = 1 + 2 + 2 = 1 + 4 = 2 + 3 = 5
void Ghi(int num)
{
cout << n << " = ";
for (int i = 1; i < num; i++)
cout << x[i] << " + ";
cout << x[num] << endl;
}
void Try(int num, int S) // S là tổng còn lại
{
for (int i = x[num-1]; i + i <= S; i++)
{
x[num] = i;
Try(num+1, S-i);
}
x[num] = S;
Ghi(num);
}
int main()
{
cin >> n;
x[0] = 1;
Try(1, n);
return 0;
}
void Ghi_Hau()
{
for (int i = 1; i <= n; i++) cout << "(" << i << ", "<< x[i] << "); ";
cout << endl;
sl ++;
}
void XepHau(int k)
{
if (k > n){
Ghi_Hau();
return;
}
for (int i = 1; i <= n; i++)
if (cot[i] == 0 && tong[i+k] == 0 && hieu[i-k+n] == 0)
{
cot[i] = tong[i+k] = hieu[i-k+n] = 1;
x[k] = i;
XepHau(k+1);
cot[i] = tong[i+k] = hieu[i-k+n] = 0;
}
}
int main()
{
cin >> n;
memset(tong, 0, sizeof(tong));
memset(hieu, 0, sizeof(hieu));
XepHau(1);
cout << "So cach xep hau la " << sl;
}
Hàm memset gán toàn bộ giá trị mảng bằng 0, chú ý bên trên khai báo thêm
#include <cstring>
Tong[i+k]: đánh dấu đường chéo x+y = i+k đã có hậu đặt chưa.
Hieu[i-k+n]: đánh dấu đường chéo x-y = i-k đã đặt hậu hay chưa, cộng thêm n để tránh chỉ số
âm.
x[k] = i : là biểu thị đặt con hậu vào ô (k, i) hay ô (k, x[k]). Mỗi hàng chỉ đặt một hậu.
0 1 2 3 4 5 6 7 8 0 1 2 3 4 5 6 7 8
0 0 1 2 3 4 5 6 7 8 0
1 9 10 11 12 13 14 15 16 17 1 (0,0) (0,1) (0,2)
2 18 19 20 21 22 23 24 25 26 2
3 27 28 29 30 31 32 33 34 35 3
4 36 37 38 39 40 41 42 43 44 4 (1,0) (1,1) (1,2)
5 45 46 47 48 49 50 51 52 53 5
6 54 55 56 57 58 59 60 61 62 6
7 63 64 65 66 67 68 69 70 71 7 (2,0) (2,1) (2,2)
8 72 73 74 75 76 77 78 79 80 8
Thay vì đánh số các hàng cột từ 1 → 9, ta sẽ đánh số 0 → 8. Các ô đánh số như hình bên trái và
đánh số các hình vuông theo hình bên phải.
Ta dễ dàng thấy một ô có thứ tự là 𝑥 (0 ≤ 𝑥 ≤ 80) thì có tọa độ hàng là 𝑖 = 𝑥/9, tọa đô cột là
𝑗 = 𝑥%9, tọa độ hình vuông 3 × 3 chứa ô đó là [𝑖/3][𝑗/3].
Duyệt đệ quy, lần lượt thử đặt các giá trị từ 1 tới 9 vào các ô trống.
Dùng thêm mảng ℎ𝑎𝑛𝑔[𝑖][𝑥] 𝑥 ∈ [1,9] để đánh dấu đã có giá trị 𝑥 ở hàng 𝑖 hay chưa.
Tương tự với mảng cot[𝑗] [𝑥]𝑣à ℎ𝑣 [𝑢][𝑣 ][𝑥] để đánh dấu cho cột 𝑗 và hình vuông 3 × 3
[𝑢][𝑣](𝑢, 𝑣 = 0,1,2)
Đoạn code được thực hiện như sau:
#include <iostream>
#include <cstring>
#include <fstream>
#include <cstdlib> // khai báo để sử dụng lệnh exit(0)
using namespace std;
int hang[10][10], cot[10][10], hv[3][3][10], a[10][10];
void nhap()
{
char ch;
for (int i = 0; i <= 8; i++)
for (int j = 0; j <= 8; j++)
{
cin >> ch;
if (ch == '.') a[i][j] = 0;
else
{
int u = ch - 48; // lấy giá trị số, không để kiểu ký tự.
hang[i][u] = cot[j][u] = hv[i/3][j/3][u] = 1;
a[i][j] = u;
}
}
}
void ghikq()
{
for (int i = 0; i <= 8; i++)
{
for (int j = 0; j <= 8; j++) cout << a[i][j];
cout << endl;
}
exit(0); // chương trình dừng hẳn khi tìm thấy phương án điền số.//khai bao #include <cstdlib>
}