Baby Ming and Matrix games
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 510 Accepted Submission(s): 114
Problem Description
These few days, Baby Ming is addicted to playing a matrix game.
Given a n∗m
matrix, the character in the matrix
(i∗2,j∗2) (i,j=0,1,2...)
are the numbers between
0−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 sum
. (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.)
Given a n∗m
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 sum
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.)
Input
In the first line contains a single positive integer
T
, indicating number of test case.
In the second line there are two odd numbers n,m
, and an integer sum(
−10
18
<sum<10
18![]()
, divisor 0 is not legitimate, division rules see example)
In the next n
lines, each line input
m
characters, indicating the matrix. (The number of numbers in the matrix is less than
15
)
1≤T≤1000
In the second line there are two odd numbers n,m
In the next n
1≤T≤1000
Output
Print Possible if it is possible to find such an expressions.
Print Impossible if it is impossible to find such an expressions.
Print Impossible if it is impossible to find such an expressions.
Sample Input
3 3 3 24 1*1 +#* 2*8 1 1 1 1 3 3 3 1*0 /#* 2*6
Sample Output
Possible Possible PossibleHintThe first sample:1+2*8=24 The third sample:1/2*6=3
卡数据精度卡的要死要活的,这种精度问题的题目,真的不适合我,怎么卡怎么WA,怎么写怎么WA、我就日了赵日天了。
最后还是参考了别人的代码过的:这里一同分享一下(还是菜。。。)
代码源:
http://blog.csdn.net/yp_2013/article/details/50573388
这里精度控制不是每个人都能控制好的东西,这里采用分数的求法控制数据的。同时还有约分的操作,至于约分怎么约呢?一个gcd搞定。
dfs的方向还是比较好想的,比赛的时候想出来了,主要是写代码的困难。。
真特么是日了狗了:
虽然结果不是很好,但是学到了东西,那就是进步~!
#include <iostream>
#include <algorithm>
#include <string.h>
#include <cmath>
#include <set>
using namespace std;
int flag;
char mp[40][40];
bool vis[40][40];
int n,m;
__int64 gcd(__int64 a,__int64 b)//寻找最大公约数。
{
if(b==0) return a;
return gcd(b,a%b);
}
__int64 sum;
int dir[4][2]={
2,0,
-2,0,
0,2,
0,-2
};
void dfs(int x,int y,__int64 zi,__int64 mu)
{
if(flag==1)
return ;
if(zi!=0)
{
__int64 yue=gcd(zi,mu);
zi/=yue;
mu/=yue;
}
if(zi==0) mu=1;//避免除的过程中有runtime error的情况。
if(mu==1&&zi==sum)
{
flag=1;
return ;
}
for(int i=0;i<4;i++)//这里边的步骤还是很好理解的,也是比较好想的。
{
int xx=x+dir[i][0];
int yy=y+dir[i][1];
if(vis[xx][yy])
continue;
int xx2=x+dir[i][0]/2;
int yy2=y+dir[i][1]/2;
if(xx>=0&&xx<n&&yy>=0&&yy<m)//控制不要出范围
{
char fu=mp[xx2][yy2];
__int64 num=mp[xx][yy]-'0';
if(fu=='/'&&num==0)
continue;
vis[xx][yy]=1;
if(fu=='/')
dfs(xx,yy,zi,mu*num);
if(fu=='*')
dfs(xx,yy,zi*num,mu);
if(fu=='+')
dfs(xx,yy,zi+mu*num,mu);
if(fu=='-')
dfs(xx,yy,zi-mu*num,mu);
vis[xx][yy]=0;
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%I64d",&n,&m,&sum);
for(int i=0;i<n;i++)
scanf("%s",mp[i]);
flag=0;
memset(vis,0,sizeof vis);
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(mp[i][j]<='9'&&mp[i][j]>='0')
{
if(flag==0)
{
vis[i][j]=1;
dfs(i,j,mp[i][j]-'0',1);
vis[i][j]=0;
}
}
}
}
if(flag)
puts("Possible");
else
puts("Impossible");
}
return 0;
}