八皇后问题
(英文:Eight queens),是由国际西洋棋棋手马克斯·贝瑟尔于1848年提出的问题,是回溯算法的典型案例。 问题表述为:在8×8格的国际象棋上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
void E_queens()//八皇后穷举法(8×8的棋盘,每一行上一个皇后,任意两个皇后都不能处于同一行、同一列或同一斜线上)
{//i第一行的列标,j第二行的列标,k……行的列标
int count = 0;//记录有几种方法
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
if (j == i || j - i == 1 || j - i == -1)
{
continue;//如果不合题意跳到下一个位置
}
for (int k = 0; k < 8; k++)
{
if (k == j||k==i || k - j == 1 || k - j == -1||k-i==2||k-i==-2)
{
continue;
}
for (int s = 0; s< 8; s++)
{
if (s == k ||s==i||s==j|| s - k == 1 || s - k == -1 || s - j == 2 || s - j == -2 || s - i == 3 || s - i == -3)
{
continue;
}
for (int m = 0; m < 8; m++)
{
if (m == s||m==k||m==j||m==i || m - s == 1 || m - s == -1 || m - k == 2 || m - k == -2 || m - j == 3 || m - j == -3 || m - i == 4 || m - i == -4)
{
continue;
}
for (int n = 0; n < 8; n++)
{
if (n == m ||n==i||n==j||n==k||n==s|| n - m == 1 || n - m == -1 || n - s == 2 || n - s == -2 || n - k == 3 || n - k == -3 || n - j == 4 || n - j == -4 || n - i == 5 || n - i == -5)
{
continue;
}
for (int p = 0; p < 8; p++)
{
if (p == n||p==m||p==i||p==j||p==k||p==s || p - n == 1 || p - n == -1 || p - m == 2 || p - m == -2 || p - s == 3 || p - s == -3 || p - k == 4 || p - k == -4 || p - j == 5 || p - j == -5 || p - i == 6 || p - i == -6)
{
continue;
}
for (int q = 0; q < 8; q++)
{
if (q == p||q==n||q==m||q==i||q==j||q==k||q==s || q - p == 1 || q - p == -1 || q - n == 2 || q - n == -2 || q - m == 3 || q - m == -3 || q - s == 4 || q - s == -4 || q - k == 5 || q - k == -5 || q - j == 6 || q - j == -6 || q - i == 7 || q - i == -7)
{
continue;
}
count++;
for (int w = 0; w< 8; w++)
{
int f;
if (w == 0)
{
f = i;
}
if (w == 1)
{
f = j;
}
if (w == 2)
{
f = k;
}
if (w == 3)
{
f = s;
}
if (w == 4)
{
f = m;
}
if (w == 5)
{
f = n;
}
if (w == 6)
{
f = p;
}
if (w == 7)
{
f = q;
}
for (int b = 0; b < 8; b++)
{
if (b != f)
printf("X ");
else
printf("Q ");//皇后的位置
}
printf("\n");
}
printf("----------------\n");
}
}
}
}
}
}
}
}
printf("一共%d种方法\n", count);
}
打印结果:
凑硬币
int coins()//凑硬币:分别有23分,29分,41分,67分的硬币,凑1808分硬币有几种方法
{
int count = 0;
for (int i = 0; i < 1808/15; i++)
{
for (int j = 0; j < 1808 / 23; j++)
{
if (i * 15 + j * 23 > 1808)
{
continue;
}
for (int k = 0; k < 1808 / 29; k++)
{
if (i * 15 + j * 23+k*29 > 1808)
{
continue;
}
for (int m = 0; m < 1808 / 41; m++)
{
if (i * 15 + j * 23 +k*29+m*41> 1808)
{
continue;
}
for (int n = 0; n < 1808 / 67; n++)
{
if (i * 15 + j * 23 + k * 29 + m * 41 + n * 67 == 1808)
{
count++;
}
}
}
}
}
}
return count;
}
输出结果19551