习题:Xor-Paths(折半搜索)

题目

传送门

思路

一道还可以的折半搜索的题目

路径的长度必然为\(n+m-1\)

如果直接暴力来做,时间复杂度即为\(2^{n+m-1}\),必然会爆炸

但是考虑到\(2^\frac{n+m-1}{2}\)的复杂度可以接受,就可以用折半搜索

剩下的用一个map来存一下几个

代码

#include<iostream>
#include<cstdio>
#include<map>
using namespace std;
int n,m;
long long k;
int dx[5]={0,1,0,-1,0};
int dy[5]={0,0,1,0,-1};
long long w[25][25],ans;
map<long long,long long> t[25][25];
bool inside(int x,int y)
{
    if(1<=x&&x<=n&&1<=y&&y<=m)
        return 1;
    return 0;
}
void dfs1(int x,int y,int dep,int limit,long long done)
{
    if(dep>limit)
    {
        t[x][y][done]++;
        return;
    }
    done^=w[x][y];
    for(int i=1;i<=2;i++)
    {
        int tx=x+dx[i];
        int ty=y+dy[i];
        if(inside(tx,ty))
            dfs1(tx,ty,dep+1,limit,done);
    }
}
void dfs2(int x,int y,int dep,int limit,long long done)
{
	done^=w[x][y];
    if(dep==limit)	
    {
        ans+=t[x][y][k^done];
        return;
    } 
    for(int i=3;i<=4;i++)
    {
        int tx=x+dx[i];
        int ty=y+dy[i];
        if(inside(tx,ty))
            dfs2(tx,ty,dep+1,limit,done);
    }
}
int main()
{
	ios::sync_with_stdio(false);
    cin>>n>>m>>k;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin>>w[i][j];
    dfs1(1,1,1,(n+m-1)/2,0);
    dfs2(n,m,1,(n+m-1)-(n+m-1)/2,0);
    cout<<ans;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/loney-s/p/13387845.html
今日推荐