P1562 还是N皇后

链接:Miku


位运算的好题

(对于位运算本蒟蒻来说太毒瘤了)


对于这题的数据范围,把八皇后的代码改一改是不够的,必须要用位运算


先上代码

#include<cstdio>
#include<iostream>
#include<cstdio>
using namespace std;
int n,ans;
int map[25];
int end;
char c;
int sign; 
int lie;
int lowbit(int x){
    return x&(-x);
}
void dfs (int now,int l,int r,int deep)
 {
     if(now==end){
         ans++;
         return ;
     }
    int sign=end&(~(now|r|l|map[deep]));
    while(sign){
        int p=lowbit(sign);
        sign-=p;
        dfs(now+p,(l+p)<<1,(r+p)>>1,deep+1);
    }
}
int main()
{
    cin>>n;
    end=(1<<n)-1;
    for(int i=1;i<=n;++i){
        for(int j=1;j<=n;++j){
            cin>>c;
            if(c=='.')
                map[i]=map[i]|(1<<(n-j));
        }
    }
    dfs(0,0,0,1);
    cout<<ans;
    return 0;
} 

Ac


首先呢,用一个数字的每一位代表一个位置的某种状态(放和不放)

然后

end=(1<<n)-1;

1表示全放上了,那么自然这个状态就是全放上了


void dfs (int now,int l,int r,int deep)
 {
     if(now==end){
         ans++;
         return ;
     }
    int sign=end&(~(now|r|l|map[deep]));
    while(sign){
        int p=lowbit(sign);
        sign-=p;
        dfs(now+p,(l+p)<<1,(r+p)>>1,deep+1);
    }
}

Ac

为什么又那么多参数呢,因为是位运算,我们完全可以把上一次的状态传下去,毕竟只是一个数,空间不大

(这也就意味着不需要回溯,因为我们直接传下去了)

既然我们用1表示已经放了,那么完全可以用这l(左对角线),r(右对角线)和now(竖着的限制)的与来找到能放的

为什么要取反呢,因为我们最后lowbit找的是最后一个1,不是0啊

但是又要和end&一下,因为~会把符号位取反

剩下的就显然了

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇