您的位置:首页 > 编程语言 > Java开发

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

2018-03-30 12:29 429 查看
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();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: