一般解法
算法思路:
對於所有的位置,判斷能不能放;
能放就放,處理;
不可行,回溯;
剪枝:
- 不能在同一行
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\n", a[n]);
}
return 0;
}
已知兩點,求所經過直線的斜率:
k = (x2 - x1) / (y2 - y1)