备考蓝桥杯(19)方格填数(DFS) java实现

package pers.robert.lanqiaobei07;
/**
 * 
剪邮票
如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。

请你计算,一共有多少种不同的剪取方法。

请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

 * @author Robert
 *
 */
public class The07JianYouPiaoDemo1_question {
	  static int a[] = new int[5];  
	           public static void main(String[] args) {  
	               int count = 0;  
	              for (a[0] = 0; a[0] < 12; a[0]++) {  
	                  for (a[1] = a[0] + 1; a[1] < 12; a[1]++) {  
	                       for (a[2] = a[1] +1 ; a[2] < 12; a[2]++) {  
	                           for (a[3] = a[2]+1; a[3] < 12; a[3]++) {  
	                              for (a[4] = a[3]+1; a[4] < 12; a[4]++) {  
	                                 if (judge()) {  
	                                     count++;  
	                                  }  
	                            }  
	                         }  
	                    }  
	                }  
	              }  
	              System.out.println(count);  
	         }  
	          private static boolean judge() {  
	             boolean visit[] = new boolean[5];  
	              dfs(visit,0);  
	             return visit[0]&&visit[1]&&visit[2]&&visit[3]&&visit[4];  
	         }  
	       
	         private static void dfs(boolean[] visit, int i) {  
	            visit[i] = true;  
	            for (int j = 0; j < visit.length; j++) {  
	            	//!visit[j]-->未被访问,a[i]/4==a[j]/4-->在同一列,a[i]==a[j]+1||a[i]==a[j]-1)-->在左右相邻两个格子
	                  if (!visit[j]&&(a[i]/4==a[j]/4)&&(a[i]==a[j]+1||a[i]==a[j]-1)) {  
	                    dfs(visit, j);  
	                 }  
	                  //!visit[j]&&(a[i]==a[j]+4||a[i]==a[j]-4)-->未被访问并且在上下相邻的两个元素
	                 if (!visit[j]&&(a[i]==a[j]+4||a[i]==a[j]-4)) {  
	                      dfs(visit, j);  
	                  }  
	           }  
	          } 

分析:采用深度优先搜索:df()

函数入口:

             dfs(visit,0);  
	 


函数体:

         private static void dfs(boolean[] visit, int i) {  
	            visit[i] = true;  
	            for (int j = 0; j < visit.length; j++) {  
	            	//!visit[j]-->未被访问,a[i]/4==a[j]/4-->在同一列,a[i]==a[j]+1||a[i]==a[j]-1)-->在左右相邻两个格子
	                  if (!visit[j]&&(a[i]/4==a[j]/4)&&(a[i]==a[j]+1||a[i]==a[j]-1)) {  
	                    dfs(visit, j);  
	                 }  
	                  //!visit[j]&&(a[i]==a[j]+4||a[i]==a[j]-4)-->未被访问并且在上下相邻的两个元素
	                 if (!visit[j]&&(a[i]==a[j]+4||a[i]==a[j]-4)) {  
	                      dfs(visit, j);  
	                  }  
	           }  

这里顺便讲解一下深度优先收缩:

  (1)      DFS(初始节点)

              (2)      Function DFS(一个节点) {

              (3)          访问该节点,并且标示已访问。

              (4)          For(遍历该节点的相邻的未访问过的节点) {

              (5)                DFS(这个邻接节点)。


#include<vector>
 
using namespace std;
int max_value, target;
 
//depth first search by recursion, not stack.
bool dfsearch(vector<int> vec) {
//judge whether to get the result and update the max value.
int len = vec.size();
for (int i = 0; i < len; i++) {
if (vec[i] == target) return true;
if (vec[i] > max_value && vec[i] < target) max_value = vec[i];
}
for (int i = 0; i < len; i++) {
for (int j = i + 1; j < len; j++) {
vector<int> temp;
for (int k = 0; k < len; k++) if (k != i && k != j) temp.push_back(vec[k]);
 
temp.push_back(vec[i] + vec[j]);
if (dfsearch(temp) == true) return true;
temp.pop_back();
 
temp.push_back(vec[i] - vec[j]);
if (dfsearch(temp) == true) return true;
temp.pop_back();
 
temp.push_back(vec[j] - vec[i]);
if (dfsearch(temp) == true) return true;
temp.pop_back();
 
temp.push_back(vec[i] * vec[j]);
if (dfsearch(temp) == true) return true;
temp.pop_back();
 
if (vec[i] == 0 || vec[j] == 0) continue;
int max_t = max(vec[i], vec[j]);
int min_t = min(vec[i], vec[j]);
if (max_t%min_t == 0) {
temp.push_back(max_t/min_t);
if (dfsearch(temp) == true) return true;
temp.pop_back();
}
}
}
return false;
}
 
int main() {
int num;
cin >> num;
while(num--) {
vector<int> vec(5);
for(int i = 0; i < 5; i++) cin >> vec[i];
max_value = -99999;
cin >> target;
if (dfsearch(vec) == true) cout << target << endl;
else cout << max_value << endl;
}
}

结束条件
if (vec[i] == target) return true;

各种各样的延伸条件:加减乘除

temp.push_back(vec[i] * vec[j]);
if (dfsearch(temp) == true) return true;
temp.pop_back();


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值