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;
}
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;
}
相关文章推荐
- USACO Checker Challenge 位运算
- USACO section 1.5 Checker Challenge(dfs深搜)
- USACO1.5 Checker Challenge(类n皇后问题)
- USACO 1.5 Checker Challenge
- USACO1.5.4 checker challenge
- USACO Section 1.5 Checker Challenge - 普普通通的皇后问题~~
- USACO section 1.5 Checker Challenge(dfs深搜)
- USACO:Checker Challenge
- USACO 1.5.4 Checker Challenge
- USACO 1.5.4 Checker Challenge ———— DFS
- USACO 1.5 Checker Challenge (checker)
- USACO1.5.4 checker challenge
- [USACO 1.5.4] Checker Challenge
- USACO 1.5.4 Checker Challenge 题解
- [usaco]1.5 Checker Challenge
- USACO6.5.5 Checker Challenge( checker)
- USACOTrainning.Checker Challenge
- usaco6.5.5 Checker Challenge
- USACO 6.5 Checker Challenge
- USACO 1.5 Checker Challenge(DFS)