0%

`八皇后问题是使用回溯算法解决的典型案例。算法的解决思路是:

  1. 从棋盘的第一行开始,从第一个位置开始,依次判断当前位置是否能够放置皇后,判断的依据为:同该行之前的所有行中皇后的所在位置进行比较,如果在同一列,或者在同一条斜线上(斜线有两条,为正方形的两个对角线),都不符合要求,继续检验后序的位置。
  2. 如果该行所有位置都不符合要求,则回溯到前一行,改变皇后的位置,继续试探。
  3. 如果试探到最后一行,所有皇后摆放完毕,则直接打印出 8*8 的棋盘。最后一定要记得将棋盘恢复原样,避免影响下一次摆放。

#include <stdio.h>
int Queenes[8] = { 0 }, Counts = 0;

//检查是否冲突
int Check(int line, int list) {
//遍历该行之前的所有行
for (int index = 0; index < line; index++) {
//挨个取出前面行中皇后所在位置的列坐标
int data = Queenes[index];
//如果在同一列,该位置不能放
if (list == data) {
return 0;
}
//如果当前位置的斜上方有皇后,在一条斜线上,也不行
if ((index + data) == (line + list)) {
return 0;
}
//如果当前位置的斜下方有皇后,在一条斜线上,也不行
if ((index - data) == (line - list)) {
return 0;
}
}
//如果以上情况都不是,当前位置就可以放皇后
return 1;
}

//输出语句
void print()
{
for (int line = 0; line < 8; line++)
{
int list;
for (list = 0; list < Queenes[line]; list++)
printf("0");
printf("#");
for (list = Queenes[line] + 1; list < 8; list++) {
printf("0");
}
printf("\n");
}
printf("================\n");
}

//回溯
void eight_queen(int line) {
//在数组中为0-7列
for (int list = 0; list < 8; list++) {
//对于固定的行列,检查是否和之前的皇后位置冲突
if (Check(line, list)) {
//不冲突,以行为下标的数组位置记录列数
Queenes[line] = list;
//如果最后一样也不冲突,证明为一个正确的摆法
if (line == 7) {
//统计摆法的Counts加1
Counts++;
//输出这个摆法
print();
//每次成功,都要将数组重归为0
Queenes[line] = 0;
return;
}
//继续判断下一样皇后的摆法,递归
eight_queen(line + 1);
//不管成功失败,该位置都要重新归0,以便重复使用。
Queenes[line] = 0;
}
}
}
int main() {
//调用回溯函数,参数0表示从棋盘的第一行开始判断
eight_queen(0);
printf("摆放的方式有%d种", Counts);
return 0;
}

1、(普通算法时间复杂度为mnp)

2、矩阵相乘的前提条件:乘号前的矩阵的列数要等于乘号后矩阵的行数。(矩阵乘法无交换律)(前行x后列)

3、计算方法是:用矩阵A的第 i 行和矩阵B中的每一列 j 对应的数值做乘法运算,乘积一一相加,所得结果即为矩阵 C 中第 i 行第 j 列的值。

实现代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include <stdio.h>
#define MAXSIZE 1200
#define MAXRC 100
#define ElemType int
typedef struct
{
int i, j;//行,列
ElemType e;//元素值
}Triple;

typedef struct
{
Triple data[MAXSIZE + 1];
int rpos[MAXRC + 1];//每行第一个非零元素在data数组中的位置
int mu, nu, tu;//行数,列数,元素个数
}RLSMatrix;

RLSMatrix MultSMatrix(RLSMatrix A, RLSMatrix B, RLSMatrix C)
{
//如果矩阵A的列数与矩阵B的行数不等,则不能做矩阵乘运算
if (A.nu != B.mu)
return C;
C.mu = A.mu;
C.nu = B.nu;
C.tu = 0;
//如果其中任意矩阵的元素个数为零,做乘法元素没有意义,全是0
if (A.tu * B.tu == 0)
return C;
else
{
int arow;
int ccol;
//遍历矩阵A的每一行
for (arow = 1; arow <= A.mu; arow++)
{
//创建一个临时存储乘积结果的数组,且初始化为0,遍历每次都需要清空
int ctemp[MAXRC + 1];
for (int i = 0; i < MAXRC + 1; i++) {
ctemp[i] = 0;
}
C.rpos[arow] = C.tu + 1;
//根据行数,在三元组表中找到该行所有的非0元素的位置
int tp;
if (arow < A.mu)
tp = A.rpos[arow + 1];//获取矩阵A的下一行第一个非零元素在data数组中位置
else
tp = A.tu + 1;//若当前行是最后一行,则取最后一个元素+1

int p;
int brow;
//遍历当前行的所有的非0元素
for (p = A.rpos[arow]; p < tp; p++)
{
brow = A.data[p].j;//取该非0元素的列数,便于去B中找对应的做乘积的非0元素
int t;
// 判断如果对于A中非0元素,找到矩阵B中做乘法的那一行中的所有的非0元素
if (brow < B.mu)
t = B.rpos[brow + 1];
else
t = B.tu + 1;
int q;
//遍历找到的对应的非0元素,开始做乘积运算
for (q = B.rpos[brow]; q < t; q++)
{
//得到的乘积结果,每次和ctemp数组中相应位置的数值做加和运算
ccol = B.data[q].j;
ctemp[ccol] += A.data[p].e * B.data[q].e;
}
}
//矩阵C的行数等于矩阵A的行数,列数等于矩阵B的列数,所以,得到的ctemp存储的结果,也会在C的列数的范围内
for (ccol = 1; ccol <= C.nu; ccol++)
{
//由于结果可以是0,而0不需要存储,所以在这里需要判断
if (ctemp[ccol])
{
//不为0,则记录矩阵中非0元素的个数的变量tu要+1;且该值不能超过存放三元素数组的空间大小
if (++C.tu > MAXSIZE)
return C;
else {
C.data[C.tu].e = ctemp[ccol];
C.data[C.tu].i = arow;
C.data[C.tu].j = ccol;
}
}
}
}
return C;
}
}

int main(int argc, char* argv[])
{
RLSMatrix M, N, T;

M.tu = 4;
M.mu = 3;
M.nu = 4;

M.rpos[1] = 1;
M.rpos[2] = 3;
M.rpos[3] = 4;

M.data[1].e = 3;
M.data[1].i = 1;
M.data[1].j = 1;

M.data[2].e = 5;
M.data[2].i = 1;
M.data[2].j = 4;

M.data[3].e = -1;
M.data[3].i = 2;
M.data[3].j = 2;

M.data[4].e = 2;
M.data[4].i = 3;
M.data[4].j = 1;

N.tu = 4;
N.mu = 4;
N.nu = 2;

N.rpos[1] = 1;
N.rpos[2] = 2;
N.rpos[3] = 3;
N.rpos[4] = 5;

N.data[1].e = 2;
N.data[1].i = 1;
N.data[1].j = 2;

N.data[2].e = 1;
N.data[2].i = 2;
N.data[2].j = 1;

N.data[3].e = -2;
N.data[3].i = 3;
N.data[3].j = 1;

N.data[4].e = 4;
N.data[4].i = 3;
N.data[4].j = 2;

T = MultSMatrix(M, N, T);
for (int i = 1; i <= T.tu; i++) {
printf("(%d,%d,%d)\n", T.data[i].i, T.data[i].j, T.data[i].e);
}
return 0;
}

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server

More info: Server

Generate static files

1
$ hexo generate

More info: Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment