寒假訓練——搜索 G - Xor-Paths
There is a rectangular grid of size n×mn×m . Each cell has a number written on it; the number on the cell (i,ji,j ) is ai,jai,j . Your task is to calculate the number of paths from the upper-left cell (1,11,1 ) to the bottom-right cell (n,mn,m ) meeting the following constraints:
- You can move to the right or to the bottom only. Formally, from the cell (
- The xor of all the numbers on the path from the cell (1,11,1 ) to the cell (n,mn,m ) must be equal to kk (xor operation is the bitwise exclusive OR, it is represented as ‘^‘ in Java or C++ and "xor" in Pascal).
Find the number of such paths in the given grid.
Input
The first line of the input contains three integers nn , mm and kk (1≤n,m≤201≤n,m≤20 , 0≤k≤10180≤k≤1018 ) — the height and the width of the grid, and the number kk .
The next nn lines contain mm integers each, the jj -th element in the ii -th line is
Output
Print one integer — the number of paths from (1,11,1 ) to (n,mn,m ) with xor sum equal to kk .
Examples
Input3 3 11Output
2 1 5
7 10 0
12 6 4
3Input
3 4 2Output
1 3 3 3
0 3 3 2
3 0 1 1
5Input
3 4 1000000000000000000Output
1 3 3 3
0 3 3 2
3 0 1 1
0
Note
All the paths from the first example:
- (1,1)→(2,1)→(3,1)→(3,2)→(3,3)(1,1)→(2,1)→(3,1)→(3,2)→(3,3) ;
- (1,1)→(2,1)→(2,2)→(2,3)→(3,3)(1,1)→(2,1)→(2,2)→(2,3)→(3,3) ;
- (1,1)→(1,2)→(2,2)→(3,2)→(3,3)(1,1)→(1,2)→(2,2)→(3,2)→(3,3) .
All the paths from the second example:
- (1,1)→(2,1)→(3,1)→(3,2)→(3,3)→(3,4)(1,1)→(2,1)→(3,1)→(3,2)→(3,3)→(3,4) ;
- (1,1)→(2,1)→(2,2)→(3,2)→(3,3)→(3,4)(1,1)→(2,1)→(2,2)→(3,2)→(3,3)→(3,4) ;
- (1,1)→(2,1)→(2,2)→(2,3)→(2,4)→(3,4)(1,1)→(2,1)→(2,2)→(2,3)→(2,4)→(3,4) ;
- (1,1)→(1,2)→(2,2)→(2,3)→(3,3)→(3,4)(1,1)→(1,2)→(2,2)→(2,3)→(3,3)→(3,4) ;
- (1,1)→(1,2)→(1,3)→(2,3)→(3,3)→(3,4)(1,1)→(1,2)→(1,3)→(2,3)→(3,3)→(3,4) .
題目:G - Xor-Paths
思路:
折半思想,前一半:從位置(1,1)開始到x+y=(n+m)/2,可以看成函數,進行異或。
後一半:從(n,m)開始,一直到x+y=(n+m)/2,異或。
異或有交換律,還有其他運算法則。
由運算法則可以推出公式
k=a1^a2^...^an;
令i=(1+n)/2;
q=a1^a2^...^ai;
sum=ai^...^an;
k=sum^ai^q;
所以q=sum^ai^k;
然後你第一個函數在走到的點給sum值打個標記,然後第二個函數把sum^ai就是取消這一步的值(這個值在前一個函數)
再^k就是找到跟現在這個sum異或起來為k(也就是合成一條路徑)標記的值,也就是方案有多少
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <map> #include <algorithm> using namespace std; typedef long long ll; const int maxn=25; ll a[maxn][maxn],ans,k; map<ll,ll>mp[maxn]; int dx[4]={0,1,0,-1}; int dy[4]={1,0,-1,0}; int n,m; void dfs_pre(int x,int y,ll sum) { if(x+y==(n+m+2)/2) {mp[x][sum]++;return ;}//x+y==(n+m+2)/2,有個+2是因為有兩種特殊情況,一個是n=1,一個是m=1 for(int i=0;i<2;i++) { int tx=x+dx[i]; int ty=y+dy[i]; if(tx<1||ty<1||tx>n||ty>m) continue; dfs_pre(tx,ty,sum^a[tx][ty]); } } void dfs_end(int x,int y,ll sum) { if(x+y==(n+m+2)/2) {ans+=mp[x][sum^k^a[x][y]];return ;} for(int i=2;i<4;i++) { int tx=x+dx[i]; int ty=y+dy[i]; if(tx<1||ty<1||tx>n||ty>m) continue; dfs_end(tx,ty,sum^a[tx][ty]); } } int main() { scanf("%d%d%I64d",&n,&m,&k); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { scanf("%I64d",&a[i][j]); } } dfs_pre(1,1,a[1][1]); dfs_end(n,m,a[n][m]); printf("%I64d\n",ans); return 0; }
寒假訓練——搜索 G - Xor-Paths