codeforces 1006 F. Xor-Paths (折半搜索+中途相遇法)
发布时间
阅读量:
阅读量
题目链接:http://codeforces.com/contest/1006/problem/F
问题描述:在一个n×m的地图中,请计算从左上角到右下角的所有路径中异或值为k的数量
解题思路:采用分步搜索的方法,在起点和终点分别进行深度优先搜索(DFS)。考虑到总步数为 (x-1)+(y-1),其中初始坐标为 (1,1),因此当 (x+y) 等于 ((m+n)+2)/2 时返回结果
#include <bits/stdc++.h>
#include <iomanip>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pb push_back
#define mkp(a,b) make_pair(a,b)
#define fi first
#define se second
#define stn(a) setprecision(a)//小数总有效位数
#define stfl setiosflags(ios::fixed)//点后位数:cout<<stfl<<stn(a);
using namespace std;
typedef long long ll;
const double PI=acos(-1);
const int inf = 0x3f3f3f3f; //9
const ll inff = 0x3f3f3f3f3f3f3f3f; //18
int n,m;
ll k,a[30][30];
unordered_map<ll,ll>mp[30];
ll ans=0;
void dfs1(int x,int y,ll now)
{
if(x+y==(m+n+2)/2)
{
mp[x][now]++; //因为此时y是唯一的,所以不用记作mp[x][y][sum]
return;
}
if(x<n) dfs1(x+1,y,now^a[x+1][y]);
if(y<m) dfs1(x,y+1,now^a[x][y+1]);
}
void dfs2(int x,int y,ll now)
{
if(x+y==(m+n+2)/2) //虽然最初的思路是两次dfs分别步数都走一半,但这里不用去管m+n的奇偶,即步数是否缺一步,两次dfs要满足的都是这个等式,从坐标的角度那么此时x,y这两点必定已经重合了,不会出现缺一步的情况
{
if(mp[x][now^a[x][y]^k]!=0) //这里now^a[x][y] 是为了退回到x,y的之前那格
ans+=mp[x][now^a[x][y]^k];
return;
}
if(x>1) dfs2(x-1,y,now^a[x-1][y]);
if(y>1) dfs2(x,y-1,now^a[x][y-1]);
}
int main()
{
cin>>n>>m>>k;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>a[i][j];
dfs1(1,1,a[1][1]);
dfs2(n,m,a[n][m]);
cout<<ans<<endl;
}
全部评论 (0)
还没有任何评论哟~
