These few days, Baby Ming is addicted to playing a matrix game.
Given a n*mn∗m matrix, the character in the matrix(i*2, j*2) \ (i, j = 0, 1, 2 ...)(i∗2,j∗2) (i,j=0,1,2...) are the numbers between 0-90−9. There are an arithmetic sign (‘+’, ‘-‘, ‘*∗’, ‘/’) between every two adjacent numbers, other places in the matrix fill with ‘#’.
The question is whether you can find an expressions from the matrix, in order to make the result of the expressions equal to the given integer sumsum. (Expressions are calculated according to the order from left to right)
Get expressions by the following way: select a number as a starting point, and then selecting an adjacent digital X to make the expressions, and then, selecting the location of X for the next starting point. (The number in same place can’t be used twice.)
In the first line contains a single positive integer TT, indicating number of test case.
In the second line there are two odd numbers n, mn,m, and an integer sum(-10^{18} < sum < 10^{18}−1018<sum<1018, divisor 0 is not legitimate, division rules see example)
In the next nn lines, each line input mm characters, indicating the matrix. (The number of numbers in the matrix is less than 1515)
1 \leq T \leq 10001≤T≤1000
Print Possible if it is possible to find such an expressions.
Print Impossible if it is impossible to find such an expressions.
3 3 3 24 1*1 +#* 2*8 1 1 1 1 3 3 3 1*0 /#* 2*6
Possible Possible PossibleHintThe first sample:1+2*8=24The third sample:1/2*6=3
dfs不会超时
#include<string> #include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<queue> #include<map> #include<cmath> using namespace std; const int maxn = 55; typedef long long LL; int T, n, m; char s[maxn][maxn]; int f[maxn][maxn]; bool flag; LL sum, aa, bb, cc; LL gcd(LL a, LL b) { return a%b ? gcd(b, a%b) : b; } void find(int x, char c, LL a, LL b) { if (c == '+') aa = a + b*x, bb = b; if (c == '-') aa = a - b*x, bb = b; if (c == '*') aa = a*x, bb = b; if (c == '/') aa = a, bb = b*x; if (aa == 0) { bb = 1; return; } if (bb == 0) return; cc = gcd(aa, bb); aa /= cc; bb /= cc; } void dfs(int x, int y, LL a, LL b) { if (b*sum == a) flag = true; if (flag || b == 0) return; f[x][y] = 1; if (x - 2 >= 0 && !f[x - 2][y]) { find(s[x - 2][y] - '0', s[x - 1][y], a, b); dfs(x - 2, y, aa, bb); } if (y - 2 >= 0 && !f[x][y - 2]) { find(s[x][y - 2] - '0', s[x][y - 1], a, b); dfs(x, y - 2, aa, bb); } if (x + 2 < n && !f[x + 2][y]) { find(s[x + 2][y] - '0', s[x + 1][y], a, b); dfs(x + 2, y, aa, bb); } if (y + 2 < m && !f[x][y + 2]) { find(s[x][y + 2] - '0', s[x][y + 1], a, b); dfs(x, y + 2, aa, bb); } f[x][y] = 0; } int main() { scanf("%d", &T); while (T--) { cin >> n >> m >> sum; memset(f, 0, sizeof(f)); for (int i = 0; i < n; i++) cin >> s[i]; flag = false; for (int i = 0; i < n&&!flag; i += 2) { for (int j = 0; j < m&&!flag; j += 2) { dfs(i, j, s[i][j] - '0', 1); } } if (flag) printf("Possible\n"); else printf("Impossible\n"); } //while (scanf("%d", &n) != EOF){} return 0; }