一. 程序题(共3题,100分)
1. (程序题, 40分)
题目编号:Exp08-Basic02,GJBook3例-12-02
题目名称:N皇后问题
题目描述:
八皇后问题由高斯(C. F. Gauss)最早在1850年提出并研究,但并未完全解决。N皇后问题指在一个N×N的棋盘上放置N个皇后,使任意两个皇后都不能互相攻击。按国际象棋规则,两个皇后,若在同一行上,或在同一列上, 或在同一条斜线上, 则她们可以互相攻击。下图即满足八皇后条件的一种棋局。
编写程序给出满足条件的棋局数目。
输入:一个正整数N(0<N≤13)输出:棋局数目
样例1:
输入: 2
输出: 0
样例2:
输入: 8
输出: 92
#include <iostream>
using namespace std;
int chess[13][13] = { 0 };
int c = 0;
int n;
int Check(int raw, int col)
{
int i, j;
for (i = 0; i < n; i++)if (chess[i][col] == 1)return 0;
for (i = raw, j = col; i >= 0 && j >= 0; i--, j--)if (chess[i][j] == 1)return 0;
for (i = raw, j = col; i >= 0 && j < n; i--, j++)if (chess[i][j] == 1)return 0;
return 1;
}
void solve(int row) {
int col;
if (row > n - 1)
{
c++;
return;
}
for (col = 0; col < n; col++)
{
if (Check(row, col))
{
chess[row][col] = 1;
solve(row + 1);
chess[row][col] = 0;
}
}
}
int main() {
cin >> n;
solve(0);
cout << c;
return 0;
}
2. (程序题, 20分)
题目编号:Exp08-Basic03
题目名称:八皇后本质不同的解
题目描述:
如上题所述,当N=8时,一共有92种可能。如果去除其中上下对称、左右对称棋局、主副对角线对称棋局和旋转后重复棋局,则有12种完全不同的棋局。编写程序,输出这12种棋局。
输入:
无
输出:
共12行,每行输出1种棋局,
例如,第一行输出 No1:1 5 8 6 3 7 2 4(冒号为西文冒号且前后无多余字符,冒号后的每个数字后均有一个西文空格),
其中No1 表示这是第1种棋局;后续数字序列表示八皇后所在位置,数值本身表示某个皇后在棋盘上的行坐标,该数值所在位置表示该皇后的列坐标(>0),例如,数字5位于序列的第2位,表示棋盘上第5行第2列有一个皇后;数字4位于序列的第8位,表示棋盘上第4行第8列有一个皇后,由此,这8个数字描述了一种棋局。12种棋局的输出顺序:字典序(参考样例)。
样例:
输入:(无)
输出: No1:1 5 8 6 3 7 2 4 No2:1 6 8 3 7 4 2 5 ……(此处省略10行,分别表示No3至No12棋局)
#include <iostream>
using namespace std;
int chess[8][8] = { 0 }, Chess[92][8][8] = { 0 }, c = 0, no = 1;
void savechess() {
for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++)
if (chess[i][j])Chess[c][i][j] = 1;
}
int check(int row, int col) {
chess[row][col] = 0;
int i, j;
for (i = 0; i < 8; i++)if (chess[i][col])return 0;
for (i = 0; i < 8; i++)if (chess[row][i])return 0;
for (i = row, j = col; i >=0 && j < 8; i--, j++)if (chess[i][j])return 0;
for (i = row, j = col; i >= 0 && j >= 0; i--, j--)if (chess[i][j])return 0;
return 1;
}
int CHECK(int n) {
for (int i = 0; i < n; i++)//Chess
{
int sum = 0;
for (int j = 0; j < 8; j++)
for (int k = 0; k < 8; k++)
{
if (Chess[n][j][k] == Chess[i][j][7 - k]) {
sum++;
if (sum == 64)return 0;
}
}
sum = 0;
for (int j = 0; j < 8; j++)
for (int k = 0; k < 8; k++)
{
if (Chess[n][j][k] == Chess[i][7 - j][k]) {
sum++;
if (sum == 64)return 0;
}
}
sum = 0;
for (int j = 0; j < 8; j++)
for (int k = 0; k < 8; k++)
{
if (Chess[n][j][k] == Chess[i][7 - k][j]) {
sum++;
if (sum == 64)return 0;
}
}
sum = 0;
for (int j = 0; j < 8; j++)
for (int k = 0; k < 8; k++)
{
if (Chess[n][j][k] == Chess[i][k][7 - j]) {
sum++;
if (sum == 64)return 0;
}
}
sum = 0;
for (int j = 0; j < 8; j++)
for (int k = 0; k < 8; k++)
{
if (Chess[n][j][k] == Chess[i][k][j]) {
sum++;
if (sum == 64)return 0;
}
}
sum = 0;
for (int j = 7; j >= 0; j--)
for (int k = 0; k < 8; k++)
{
if (Chess[n][j][k] == Chess[i][7 - k][7 - j]) {
sum++;
if (sum == 64)return 0;
}
}
sum = 0;
for (int j = 0; j < 8; j++)
for (int k = 7; k >= 0; k--)
{
if (Chess[n][j][k] == Chess[i][7 - k][7 - j]) {
sum++;
if (sum == 64)return 0;
}
}
sum = 0;
for (int j = 0; j < 8; j++)
for (int k = 7; k >= 0; k--)
{
if (Chess[n][j][k] == Chess[i][7 - j][7 - k]) {
sum++;
if (sum == 64)return 0;
}
}
sum = 0;
}
return 1;
}
void print(int n) {
printf("No%d:", no);
for (int i = 0; i < 8; i++)
for (int j = 0; j < 8; j++)
if (Chess[n][i][j])cout << j + 1 << " ";
no++;
cout << endl;
}
void solve() {
for (int i = 0; i < 92; i++)
{
if (CHECK(i))print(i);
}
}
void queen(int row) {
int col;
if (row > 7) {
savechess();
c++;
if (c == 92)solve();
return;
}
for (col = 0; col < 8; col++)
{
if (check(row, col))
{
chess[row][col] = 1;
queen(row + 1);
chess[row][col] = 0;
}
}
}
int main() {
queen(0);
return 0;
}
3. (程序题, 40分)
题目编号:Exp08-Basic01,GJBook3-12-05
题目名称:正整数分解
题目描述:正整数n,按第一项递减的顺序依次输出其和等于n的所有不增的正整数和式。
输入:一个正整数n(0<n≤15)。
输出:每行输出如样例所示,和等于n的不增正整数和式,数字和运算符间无符号,最后一行结尾有一个回车换行符。
样例:
输入: 4
输出: 4=3+1 4=2+2 4=2+1+1 4=1+1+1+1
#include <iostream>
using namespace std;
int a[100], p = 0, sum;
void dfs(int m, int n) {
if (m == 0) {
cout << sum << "=";
for (int i = 0; i < p - 1; i++)cout << a[i] << "+";
cout << a[p - 1] << endl;
}
for (int i = n; i; i--) {
a[p++] = i;
if (m - i >= 0)dfs(m - i, i);
p--;
}
}
int main() {
cin >> sum;
dfs(sum, sum - 1);
return 0;
}