1. 程式人生 > >CF#498 1006F Xor-Paths

CF#498 1006F Xor-Paths

題意:一個n * m的矩陣,求從左上走到右下經過的數異或和為k的方案數。

題解:

  因為資料範圍較小,所以我們可以採用meet in the middle過掉此題、、、

  然而define inf LL 才過。。。。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define R register int
 4 #define AC 22
 5 #define LL long long
 6 #define int LL
 7 
 8 int n, m;
 9 LL k, ans;
10 LL s[AC][AC]; 11 12 map<int, LL> Map[AC]; 13 14 inline LL read() 15 { 16 LL x = 0;char c = getchar(); 17 while(c > '9' || c < '0') c = getchar(); 18 while(c >= '0' && c <= '9') x = x * 10ll + c - '0', c = getchar(); 19 return x; 20 } 21 22 void pre()
23 { 24 n = read(), m = read(), k = read(); 25 for(R i = 1; i <= n; i ++) 26 for(R j = 1; j <= m; j ++) s[i][j] = read(); 27 } 28 29 void dfs1(int x, int y, LL now)//從左上角開始往對角線搜 30 { 31 if(x < 1 || x > n || y < 1 || y > m) return ; 32 if(x + y == (n + m + 2
) / 2) {++ Map[x][now]; return;} 33 dfs1(x + 1, y, now ^ s[x + 1][y]); 34 dfs1(x, y + 1, now ^ s[x][y + 1]); 35 } 36 37 void dfs2(int x, int y, LL now)//從右下角開始往對角線搜 38 { 39 if(x < 1 || x > n || y < 1 || y > m) return ; 40 if(x + y == (n + m + 2) / 2) {ans += Map[x][now ^ s[x][y]]; return ;}//不能把同一個數異或2次。 41 dfs2(x - 1, y, now ^ s[x - 1][y]); 42 dfs2(x, y - 1, now ^ s[x][y - 1]); 43 } 44 45 signed main() 46 { 47 freopen("in.in", "r", stdin); 48 pre(); 49 dfs1(1, 1, s[1][1]); 50 dfs2(n, m, k ^ s[n][m]);//因為x ^ y = k ----> x ^ k = y 51 printf("%lld\n", ans); 52 fclose(stdin); 53 return 0; 54 }
View Code