码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces 1006F

时间:2018-07-21 22:42:45      阅读:242      评论:0      收藏:0      [点我收藏+]

标签:中间   位置   com   不能   using   tin   boa   oar   color   

题意略。

思路:

双向bfs。

技术分享图片

 

如图,对于曼哈顿距离为5的地方来说,除去两端的位置,其他位置的状态不会超过曼哈顿距离为4的地方的状态的两倍。

所以,最大曼哈顿距离为n + m。最多的状态不过2 ^ (n + m)。

这个复杂度我们不能接受,但是如果我们从两边向中间bfs的话, 每次bfs的复杂度为2 ^ ((n + m)/2)。

所以可以用双向广搜来解决。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 25;

struct point{
    int x,y;
    LL state;
    point(int a = 0,int b = 0){
        x = a,y = b;
    }
    point operator+ (const point& p){
        return point(x + p.x,y + p.y);
    }
    int sum(){
        return x + y;
    }
    bool operator< (const point& p) const{
        if(x != p.x) return x < p.x;
        else if(y != p.y) return y < p.y;
        else return state < p.state;
    }
};

point mov1[] = {point(1,0),point(0,1)};
point mov2[] = {point(-1,0),point(0,-1)};

LL board[maxn][maxn];
LL n,m,k;
map<point,LL> mp;

void bfs1(point s){
    int line = ((n + m)>>1) + 1;
    s.state = board[s.x][s.y];
    queue<point> que;
    que.push(s);
    while(que.size()){
        point temp = que.front();
        que.pop();
        if(temp.sum() == line){
            ++mp[temp];
            continue;
        }
        for(int i = 0;i < 2;++i){
            point nxt = temp + mov1[i];
            if(nxt.x > n || nxt.y > m) continue;
            nxt.state = temp.state xor board[nxt.x][nxt.y];
            que.push(nxt);
        }
    }
}
LL bfs2(point s){
    LL ret = 0;
    int line = ((n + m)>>1) + 1;
    s.state = k xor board[s.x][s.y];
    queue<point> que;
    que.push(s);
    while(que.size()){
        point temp = que.front();
        que.pop();
        if(temp.sum() == line){
            ret += mp[temp];
            continue;
        }
        for(int i = 0;i < 2;++i){
            point nxt = temp + mov2[i];
            if(nxt.x < 1 || nxt.y < 1) continue;
            nxt.state = temp.state xor board[nxt.x][nxt.y];
            que.push(nxt);
        }
    }
    return ret;
}

int main(){
    scanf("%lld%lld%lld",&n,&m,&k);
    for(int i = 1;i <= n;++i){
        for(int j = 1;j <= m;++j){
            scanf("%lld",&board[i][j]);
        }
    }
    bfs1(point(1,1));
    int line = ((n + m)>>1) + 1;
    for(int i = 1;i <= n;++i){
        int j = line - i;
        if(j <= 0) continue;
        board[i][j] = 0;
    }
    LL ans = bfs2(point(n,m));
    printf("%lld\n",ans);
    return 0;
}

 

Codeforces 1006F

标签:中间   位置   com   不能   using   tin   boa   oar   color   

原文地址:https://www.cnblogs.com/tiberius/p/9348030.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!