ZJYYC1486. 算式接龙(dfs)

题目链接:ZJYYC在线测评系统 (creative3605.com)

1:判断xy是否合法
bool legal(int x,int y){
	if(x<n && y<m && x>=0 && y>=0)return true;
	return false;
}

 

2:加减乘除运算

 

int ji(int a,int f,int b){
	int c1;
	if(f==25){
		c1= a+b;
	}else if(f==26){
		c1= a-b;
	}else if(f==27){
		c1= a*b;
	}else if (f==28){
		c1=a/b;
	}
	return c1;
}
3:转数字

 

int zhuan(string s){
	int c2;
	if(s.size()==1 && (s[0]<'0' || s[0]>'9')){//是符号 
		if(s[0]=='+')return 25;
		if(s[0]=='-')return 26;
		if(s[0]=='*')return 27;
		if(s[0]=='/')return 28; 
	}else if(s.size()==1 && s[0]<='9' && s[0]>='0'){//是一位正数 
		return s[0]-'0';
	}else if(s.size()==2){
		if(s[0]=='-'){//一位负数 
			return 0-(s[1]-'0');
		}else{//二位整数 
			return (s[0]-'0')*10+(s[1]-'0');
		}
		
	}else if(s.size()==3){//二位负数 
		///!!!!!!!!!!!!!!!!!!!!!!
		return 0-( (s[1]-'0')*10 + s[2]-'0' );
	}
}
4:dfs需要找到一个合法的符合和和法的数才递归注意要判÷与零

 

bool flag;
void dfs(int x,int y,int value){
	if(value==num){//出口 
		flag=true;
		return ;
	}
	int fu;
	for(int i=0;i<4;i++){
		int tx,ty;
		tx=x+dir[i][0];
		ty=y+dir[i][1];
		if( legal(tx,ty) && !vis[tx][ty]){//判断合法 
			if(mp[tx][ty] >20 ){//寻找符号 
				fu=mp[tx][ty];
				for(int j=0;j<4;j++){
					int txx,tyy;
					txx=tx+dir[j][0];
					tyy=ty+dir[j][1];
					if(legal(txx,tyy) && !vis[txx][tyy] ){//判断合法 
						if( abs(mp[txx][tyy]) <=20 ){//寻找第二个数 
                            if(fu==28 && mp[txx][tyy]==0)continue;
							vis[tx][ty]=true; vis[txx][tyy]=true;
//							cout<<"		txx:"<<txx<<" tyy:"<<tyy<<" value:"<<ji(value,fu,huan( mp[txx][tyy]) )<<endl;
							dfs(txx,tyy,ji(value,fu,mp[txx][tyy]) );//下一步 
							
							vis[tx][ty]=false; vis[txx][tyy]=false;	//回溯					
						}
					}
				}
			}
		}
		if(flag)return ;
	}
}

 

完整代码
#include<bits/stdc++.h>
using namespace std;
int n,m;
int num;
int mp[10][10];
bool vis[10][10];
int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
bool legal(int x,int y){
	if(x<n && y<m && x>=0 && y>=0)return true;
	return false;
}
int ji(int a,int f,int b){
	int c1;
	if(f==25){
		c1= a+b;
	}else if(f==26){
		c1= a-b;
	}else if(f==27){
		c1= a*b;
	}else if (f==28){
		c1=a/b;
	}
	return c1;
}
int zhuan(string s){
	int c2;
	if(s.size()==1 && (s[0]<'0' || s[0]>'9')){//是符号 
		if(s[0]=='+')return 25;
		if(s[0]=='-')return 26;
		if(s[0]=='*')return 27;
		if(s[0]=='/')return 28; 
	}else if(s.size()==1 && s[0]<='9' && s[0]>='0'){//是一位正数 
		return s[0]-'0';
	}else if(s.size()==2){
		if(s[0]=='-'){//一位负数 
			return 0-(s[1]-'0');
		}else{//二位整数 
			return (s[0]-'0')*10+(s[1]-'0');
		}
		
	}else if(s.size()==3){//二位负数 
		///!!!!!!!!!!!!!!!!!!!!!!
		return 0-( (s[1]-'0')*10 + s[2]-'0' );
	}
}
int huan(char a){
	return a-'0';
}
bool flag;
void dfs(int x,int y,int value){
	if(value==num){//出口 
		flag=true;
		return ;
	}
	int fu;
	for(int i=0;i<4;i++){
		int tx,ty;
		tx=x+dir[i][0];
		ty=y+dir[i][1];
		if( legal(tx,ty) && !vis[tx][ty]){//判断合法 
			if(mp[tx][ty] >20 ){//寻找符号 
				fu=mp[tx][ty];
				for(int j=0;j<4;j++){
					int txx,tyy;
					txx=tx+dir[j][0];
					tyy=ty+dir[j][1];
					if(legal(txx,tyy) && !vis[txx][tyy] ){//判断合法 
						if( abs(mp[txx][tyy]) <=20 ){//寻找第二个数 
                            if(fu==28 && mp[txx][tyy]==0)continue;
							vis[tx][ty]=true; vis[txx][tyy]=true;
//							cout<<"		txx:"<<txx<<" tyy:"<<tyy<<" value:"<<ji(value,fu,huan( mp[txx][tyy]) )<<endl;
							dfs(txx,tyy,ji(value,fu,mp[txx][tyy]) );//下一步 
							
							vis[tx][ty]=false; vis[txx][tyy]=false;	//回溯					
						}
					}
				}
			}
		}
		if(flag)return ;
	}
}
int main(){
	while(cin>>n>>m){
		memset(vis,false,sizeof(vis) );
		flag=false;
		string s1;
		for(int i=0;i<n;i++){
			for(int j=0;j<m;j++){
				cin>>s1;
				mp[i][j]=zhuan(s1);

			}
		}
		cin>>num;
		for(int i=0;i<n;i++){
			for(int j=0;j<m;j++){
				if(abs(mp[i][j]) <=20 ){//找到数字 
					vis[i][j]=true;
//					cout<<"i:"<<i<<" j:"<<j<<" value:"<<huan(mp[i][j])<<endl;
					dfs(i,j,mp[i][j]) ;
					vis[i][j]=false;
					if(flag)break;
				}
			}
			if(flag)break;
		}
		if(flag){
			cout<<"YES";
		}else{
			cout<<"NO";
		}
		cout<<endl;
	}
} 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值