您的位置:首页 > 其它

USACO 1.4 Checker Challenge 位运算

2015-01-24 10:50 309 查看
Test 1: TEST OK [0.003 secs, 3372 KB]
Test 2: TEST OK [0.003 secs, 3372 KB]
Test 3: TEST OK [0.003 secs, 3372 KB]
Test 4: TEST OK [0.003 secs, 3372 KB]
Test 5: TEST OK [0.003 secs, 3372 KB]
Test 6: TEST OK [0.008 secs, 3372 KB]
Test 7: TEST OK [0.011 secs, 3372 KB]
Test 8: TEST OK [0.078 secs, 3372 KB]

简]单介绍一下思想。

用位运算的方法来求的数量,DFS暴力搜索,搜出前3个答案。

还有一个就是棋盘是左右对称的,8*8的棋盘,第一个旗子放在第一排的前四个,和后四个结果应该完全一样。

对于棋盘n的奇偶分情况考虑一下就行了。 对半剪枝,实际上已经可以通过了。

对于非位运算的搜索还有一个优化,就是对于列是否被占用的判断,可以直接用链表,利用dancing link的思想,在穷举到最后的矩阵是很稀疏的,节约了穷举的时间。其实只加这一个优化不对半剪枝也是可以通过的~

当然最强的还是位运算,应为他对于穷举可以占用的格子的效率是最高的。

用3个数字分别表示,第deep行,每个格子的列,左斜排,右斜排是否被占用。

因为  对于deep行,他的左斜排被占用的是第一个,第二个格子。 那么deep+1行的时候,就是第0个,第一个格子。 说白了,就是这些会占用斜排的情况,在deep+1的时候,是会位移的。

位移?当然就是位运算的shl  shr了~ 到这里基本方法就出来了。  听说这是穷举N皇后最快的方法。不知道用bitset的STL的话效率怎么样。

ultimate = (1 << n) - 1;

ultimate是用来表示一个n位的二进制全是1的数字。 这个应该不复杂。

/*
TASK:checker
LANG:C++
*/
#include <cstdio>

int ultimate, n, ans(0);
int tmp,outputbuff[13],ifstop=0;;
bool a[3][35] = {0};

void dfs(int row, int ld, int rd)
{
if (row == ultimate)
{
++ ans;
return;
}
rd >>= 1, ld <<= 1;
int tmp = row | ld | rd, p, ok = (~(row | ld | rd)) & ultimate;
while (ok)
{
p = ok & -ok;
dfs(row | p, ld | p, rd | p);
ok ^= p;
}
}

void get_ans(int deep)
{
if (ifstop == 3) return;
if (deep == n)
{
++ifstop;
for (int i = 0; i != n - 1; ++ i) printf("%d ",outputbuff[i] + 1);
printf("%d\n", outputbuff[n - 1] + 1);
return;
}
for (int i = 0; i != n; ++ i)
if (!a[0][i] && !a[1][deep - i + n + 1] && !a[2][i + deep])
{
a[0][i] = a[1][deep - i + n + 1] = a[2][i + deep] = 1;
outputbuff[deep] = i;
get_ans(deep + 1);
a[0][i] = a[1][deep - i + n + 1] = a[2][i + deep] = 0;
}
}

int main()
{
freopen("checker.in", "r", stdin);
freopen("checker.out", "w", stdout);
scanf("%d",&n);
get_ans(0);
ultimate = (1 << n) - 1;
#define p (1<<(i-1))
for (int i = 1; i <= (tmp = n >> 1); ++ i) dfs(p, p, p);
ans <<= 1;
if (n&1) dfs(1 << tmp, 1 << tmp, 1 << tmp);
printf("%d\n", ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: