题解 CF1006F 【Xor-Paths】
第一个双向dfs
啊
题目翻译
有n*m的格子,从(1,1)走到(n,m),只能向下/右走。 每个格子上有权值,求走过格子的权值的异或和=k的方案数
(语文太差了我尽力了
从前往后搜,然后从后往前搜 到对角线上的点就停下,统计方案数
代码 ———————————————————————————————
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#include<cmath>
#include<map>
#define ll long long
using namespace std;
map<ll,ll>mp[21][21];//我觉得int也可以emmmm
ll tot,k,a[21][21];
ll n,m;
void dfs(ll x1,ll y1,ll v1)//x1,y1:坐标;v1:异或和
{
if(x1+y1==n+1)//对角线
{
mp[x1][y1][v1]++;//到这里,异或和是v
return;
}
if(x1<n)dfs(x1+1,y1,v1^a[x1+1][y1]);
if(y1<m)dfs(x1,y1+1,v1^a[x1][y1+1]);//往后搜
}
void dfss(ll x2,ll y2,ll v2)
{
if(x2+y2==n+1)
{
tot+=mp[x2][y2][v2^k^a[x2][y2]];
//上一句:~~组织语言……emmm……弃疗~~
//见下面吧。。。dalao随意。。。~~比我菜的真的有吗。。不写可以吗。。~~
return;
}
if(x2>1)dfss(x2-1,y2,v2^a[x2-1][y2]);
if(y2>1)dfss(x2,y2-1,v2^a[x2][y2-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];
dfs(1,1,a[1][1]);
dfss(n,m,a[n][m]);//没了
cout<<tot;
}
上面的那个地方
1.不要把x1,y1..再。亦或。一遍。了。^的逆运算就是^, a^b^b=a. 还有a^b=c则a^c=b.
2.上面统计了到x1,y1的异或和为v1的方案数。我们就硬生生把它接起来,如果这次搜索到x1,y1的异或和为v1^k,那么就是有mp[x1][y1][v1]的方案了
3.没有3
另外,不用回溯也无所谓判重。毕竟他好像走不回来
再另外。。感谢一下wjh和zhn。。大佬