1.硬币组合问题
在一个陌生的国度,有5种不同的硬币单位:15、23、29、41和67(分)。寻找所有组成18元8分(即808分)的可能组合。
假定对于所有面值的硬币你都有足够的硬币。
思路:
1.定义一个数组coins[],在其中放入5种硬币的面值。
2.使用嵌套循环来穷举所有可能的硬币组合。外层循环控制第一种硬币的数量,内层循环控制第二种硬币的数量,以此类推。
3.在每一次循环中,计算当前组合的总值,并检查是否等于目标值。如果等于目标值,则打印该组合。
#include <stdio.h>
int main() {
int coins[] = { 15, 23, 29, 41, 67 };
//动态计算硬币数组的元素个数
//int numCoins = sizeof(coins) / sizeof(coins[0]); int sum = 808;
printf("满足条件的硬币组合:\n");
// 穷举所有可能的硬币组合
for (int a = 0; a <= sum / coins[0]; a++) {
for (int b = 0; b <= sum / coins[1]; b++) {
for (int c = 0; c <= sum / coins[2]; c++) {
for (int d = 0; d <= sum / coins[3]; d++) {
for (int e = 0; e <= sum / coins[4]; e++) {
int total = a * coins[0] + b * coins[1] + c * coins[2] + d * coins[3] + e * coins[4];
if (total == sum) {
printf("%d个15分 + %d个23分 + %d个29分 + %d个41分 + %d个67分\n", a, b, c, d, e);
}
}
}
}
}
}
return 0;
}
2.八皇后问题
八个皇后,分布在八行八列,任意两个皇后不能在同一行(每一行一定有一个皇后),任意两个皇后不能在同一列。
任意两个皇后不能成45度或135度,统计所有皇后能存放的位置和总数。
思路:
1.使用嵌套循环穷举所有的皇后位置组合,将每行各列依次初始化为1(即皇后)。
// 使用穷举法搜索所有皇后的位置
int board[8][8]; // 棋盘,0表示空格,1表示皇后
void findQueenPlace() {
int count = 0; // 解决方案计数器
// 遍历所有可能的皇后位置组合
for (int c0 = 0; c0 < 8; c0++) {
for (int c1 = 0; c1 < 8; c1++) {
for (int c2 = 0; c2 < 8; c2++) {
for (int c3 = 0; c3 < 8; c3++) {
for (int c4 = 0; c4 < 8; c4++) {
for (int c5 = 0; c5 < 8; c5++) {
for (int c6 = 0; c6 < 8; c6++) {
for (int c7 = 0; c7 < 8; c7++) {
// 将当前位置设置为皇后位置
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
board[i][j] = 0;
}
}
board[0][c0] = 1;
board[1][c1] = 1;
board[2][c2] = 1;
board[3][c3] = 1;
board[4][c4] = 1;
board[5][c5] = 1;
board[6][c6] = 1;
board[7][c7] = 1;
}
}
}
}
}
}
}
}
}
2.实现一个判断函数,判断皇后位置是否满足题目所给条件:
1.检查同一列皇后是否冲突
2.检查两条对角线上皇后是否冲突
// 检查当前位置(row, col)是否可以放置皇后
int isRight(int row, int col) {
// 检查同一列是否冲突
for (int i = 0; i < row; i++) {
if (board[i][col] == 1) {
return 0;
}
}
// 检查右下到左上的对角线是否冲突
for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
if (board[i][j] == 1) {
return 0;
}
}
// 检查左下到右上的对角线是否冲突
for (int i = row - 1, j = col + 1; i >= 0 && j < 8; i--, j++) {
if (board[i][j] == 1) {
return 0;
}
}
return 1;
}
3.将满足条件的解法打印,并记录解法总数。
// 打印棋盘
void printBoard() {
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
printf("%c ", board[i][j] == 1 ? 'Q' : '.');
}
printf("\n");
}
printf("\n");
}
题解如下:
#include <stdio.h>
int board[8][8]; // 棋盘,0表示空格,1表示皇后
// 打印棋盘
void printBoard() {
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
printf("%c ", board[i][j] == 1 ? 'Q' : '.');
}
printf("\n");
}
printf("\n");
}
// 检查当前位置(row, col)是否可以放置皇后
int isRight(int row, int col) {
// 检查同一列是否冲突
for (int i = 0; i < row; i++) {
if (board[i][col] == 1) {
return 0;
}
}
// 检查左上到右下的对角线是否冲突
for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
if (board[i][j] == 1) {
return 0;
}
}
// 检查右上到左下的对角线是否冲突
for (int i = row - 1, j = col + 1; i >= 0 && j < 8; i--, j++) {
if (board[i][j] == 1) {
return 0;
}
}
return 1;
}
// 使用穷举法搜索所有皇后的位置
void findQueenPlace() {
int count = 0; // 解决方案计数器
// 遍历所有可能的皇后位置组合
for (int c0 = 0; c0 < 8; c0++) {
for (int c1 = 0; c1 < 8; c1++) {
for (int c2 = 0; c2 < 8; c2++) {
for (int c3 = 0; c3 < 8; c3++) {
for (int c4 = 0; c4 < 8; c4++) {
for (int c5 = 0; c5 < 8; c5++) {
for (int c6 = 0; c6 < 8; c6++) {
for (int c7 = 0; c7 < 8; c7++) {
// 将当前位置设置为皇后位置
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
board[i][j] = 0;
}
}
board[0][c0] = 1;
board[1][c1] = 1;
board[2][c2] = 1;
board[3][c3] = 1;
board[4][c4] = 1;
board[5][c5] = 1;
board[6][c6] = 1;
board[7][c7] = 1;
// 检查当前棋盘是否满足条件
int isRightBoard = 1;
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
// 判断皇后位置
if (board[i][j] == 1) {
if (! isRight(i, j)) {
isRightBoard = 0;
break;
}
}
}
// 减少循环次数
if (! isRightBoard) {
break;
}
}
// 如果当前棋盘满足八皇后规则,则输出该解决方案
if (isRightBoard) {
count++;
printf("解法 %d :\n", count);
printBoard();
}
}
}
}
}
}
}
}
}
// 输出解决方案的总数
printf("综上,共有 %d 种解决方法 \n", count);
}
int main() {
findQueenPlace();
return 0;
}