吉林大学-实验08 结构化程序设计(2021级)

一. 程序题(共3题,100分)

1. (程序题, 40分)

题目编号:Exp08-Basic02,GJBook3例-12-02

题目名称:N皇后问题

题目描述:

八皇后问题由高斯(C. F. Gauss)最早在1850年提出并研究,但并未完全解决。N皇后问题指在一个N×N的棋盘上放置N个皇后,使任意两个皇后都不能互相攻击。按国际象棋规则,两个皇后,若在同一行上,或在同一列上, 或在同一条斜线上, 则她们可以互相攻击。下图即满足八皇后条件的一种棋局。

编写程序给出满足条件的棋局数目。

Exp08-Basic02.jpg

输入:一个正整数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;
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值