hdu(5612)——Baby Ming and Matrix games

题意:

问题描述
铭宝宝喜欢玩游戏,这两天他喜欢玩下面这个游戏了。
给出一个n*mnm的矩阵,矩阵的(i*2,j*2)(i2,j2) (其中i, j = 0, 1, 2...i,j=0,1,2...) 位置上为0~9的数字,矩阵中每两个数字中间有一个算术符号(+、-、*、/),其他位置用#填充。
问题是:是否能在上述矩阵中,找到一个表达式,使得表达式的计算结果为给出的sum(表达式从左到右计算)
表达式按照如下方式获取:选择一个数字作为起点,每次选择相邻的数字XX进行一次计算,把得到的结果保存在数字XX上,并选择该位置为下一个起点(同一个位置的数字不能使用22次)。
输入描述
输入T(T \leq 1,000)T(T1,000)表示测试组数
输入33个数,奇数n,mn,m以及整数sumsum(除0的式子是不合法的,除法规则见样例,-10^{18} < sum < 10^{18}1018<sum<1018)
接下来输入nn行,每行mm个字符,表示给出的矩阵(矩阵内的数字个数\leq 1515
输出描述
输出Possible,表示能够找到这样的表达式
输出Impossible,表示不能够找到这样的表达式
输入样例
3
3 3 24
1*1
+#*
2*8
1 1 1
1
3 3 3
1*0
/#*
2*6
输出样例
Possible
Possible
Possible
Hint
第一组样例:1+2*8=24
第三组样例:1/2*6=3

思路:

比赛的时候想到是dfs了。。没敲,sad- -

这道题wa搞了我一个下午的原因是:只有当满足条件的时候才进行标记,所以我们要先进行筛选,只有当满足条件的时候才进行标记!!!

#include<cstdio>
#include<cstring>
#include<map>
#include<set>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
typedef __int64 ll;
typedef unsigned __int64 ULL;
#define inf 99999999
#define maxn 110
int vis[maxn][maxn];
char a[maxn][maxn];
int n,m,ff=0;
ll sum;
int dx[4]={0,1,0,-1},dy[4]={1,0,-1,0};
void dfs(int x,int y,ll zi,ll mu){
    if(mu&&zi%mu==0){
        if((ll)(zi/mu)==sum){
            ff=1;
            return ;
        }
    }
    for(int i=0;i<4;i++){
        int xx=x+dx[i];
        int yy=y+dy[i];
        int xxx=xx+dx[i];
        int yyy=yy+dy[i];
        if(vis[xxx][yyy]) continue;
        if(xx<0||yy<0||xx>n-1||yy>m-1) continue;
        if(xxx<0||yyy<0||xxx>n-1||yyy>m-1) continue;
        if(a[xx][yy]=='#') continue;
        char aa=a[xx][yy];
        if(a[xxx][yyy]>='0'&&a[xxx][yyy]<='9'){
            ll tmp=(a[xxx][yyy]-'0');
            //少了下面那句就wa了,因为这也是条件之一
            if(aa=='/'&&(mu==0||tmp==0)) continue;
            vis[xxx][yyy]=1;    //然后才进行标记!!
            if(aa=='+'){
                dfs(xxx,yyy,zi+tmp*mu,mu);
                vis[xxx][yyy]=0;
            }
            else if(aa=='-'){
                dfs(xxx,yyy,zi-tmp*mu,mu);
                vis[xxx][yyy]=0;
            }
            else if(aa=='*'){
                dfs(xxx,yyy,zi*tmp,mu);
                vis[xxx][yyy]=0;
            }
            else if(aa=='/'&&mu&&tmp){
                dfs(xxx,yyy,zi,mu*tmp);
                vis[xxx][yyy]=0;
            }
        }
    }
}
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
       ff=0;
       scanf("%d%d%I64d",&n,&m,&sum);
       for(int i=0;i<n;i++) scanf("%s",a[i]);
       for(int i=0;i<n;i++){
          for(int j=0;j<m;j++){
            if(a[i][j]>='0'&&a[i][j]<='9'){
                memset(vis,0,sizeof(vis));
                int shu=(a[i][j]-'0');
                vis[i][j]=1;
                dfs(i,j,shu,1);
                if(ff) break;
            }
          }
          if(ff) break;
       }
       if(ff) printf("Possible\n");
       else printf("Impossible\n");
    }
    return 0;
}
/*
3
3 3 24
1*1
+#*
2*8
1 1 1
1
3 3 3
1*0
/#*
2*6
*/



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值