一般解法
-
算法思路:
-
对于所有的位置,判断能不能放;
-
能放就放,处理;
-
不可行,回溯;
-
-
剪枝:
- 不能在同一行
deep++;
-
不能在同一列
-
不能在同一斜线
check k; for(i = 1; i <= deep; i++) col[i] != k; //同行 abs(i - deep) != abs(col[i] - k);//同斜线
二进制解法
row : 置1的位置表示当前列被占用 , 如 0 0 0 0 1
ld : 置1的位置表示当前左斜线被占用 , 如 0 0 0 1 0
rd : 置1的位置表示当前右斜线被占用 , 如 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 1 0 1 0 1
0 0 0 0 0 ---> 0 0 0 1 0 ---> 0 1 1 0 0 ---> 1 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1
0 0 0 0 0 0 0 0 1 1 0 1 1 1 1 1 1 1 0 1
1 1 1 1 1 1 1 1 0 0 1 0 0 0 0 0 0 0 1 0
. . . .
// 从右侧的列开始 向左判
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <queue>
#include <map>
#include <stack>
#include <deque>
#include <iostream>
using namespace std;
typedef long long LL;
const LL N = 200009;
int check, sum;
void test(int row, int ld, int rd)
{
int pos, p;
if (row != check)
{
pos = check & ~(row | ld | rd); //获得所有可以放的位置
while (pos) //从右向左尝试所有可以放的位置
{
p = pos & (~pos + 1); // 获得当前最右侧的位置
pos -= p; // 标记该位置
test(row + p, (ld + p) << 1, (rd + p) >> 1); // 把该位加到列上去,把该位加到斜线上去后 整体平移
}
}
else
{
sum++;
}
}
int main()
{
int i, j, n;
int a[15];
for (i = 1; i <= 10; i++)
{
check = (1 << i) - 1;
sum = 0;
test(0, 0, 0);
a[i] = sum;
}
while(scanf("%d", &n) != EOF && n )
{
printf("%d
", a[n]);
}
return 0;
}
已知两点,求所经过直线的斜率:
k = (x2 - x1) / (y2 - y1)