回溯算法

 

今天在论坛里看到一个关于回溯算法的题目,觉得不错,菜鸟就直接拿来了,起步阶段,抓紧努力啊!!(代码更多的为了提高自己,其中借鉴了wangjun8659的思想,不要追究版权啊,俺木有恶意.http://blog.csdn.net/wanjun8659/article/details/7491780)

一条贪吃的蛇在一个n*m的网格中游走,它只能从一个方格走向另一个相邻的方格,这里相邻的意思是两个方格有公共边。每个方格可以看作是一个房间,其中一些是空的,一些存放有苹果。贪吃的蛇根本不进入空的房间,而进入有苹果的房间后就可以带走所有苹果使房间成为空的。蛇从一个指定的房间出发,最终回到它的家,把一路带来的苹果存储到家中,当然,它希望带来的苹果最多。请编写程序,输入有整数n和m,及n*m的一个矩阵,矩阵元素数值中有一个是 -1,表示蛇的出发位置,有一个是 -2,表示蛇的家的位置,其余数值是非负整数,0表示房间为空,非零整数表示苹果的数目。输出蛇选择的游走路径和获得的最多的苹果数目。

例如输入4*4矩阵:
7  0  4   18
4  0  1   1
15 7  11 -1
0 12 -2  0

则应输出 (2, 3), (1, 3), (0, 3), (0, 2), (1, 2), (2, 2), (2, 1), (3, 1), (3, 2), 带回苹果数为1+18+4+1+11+7+12 = 54。

(本题为2011年ACM大赛题目)。(可查阅:吕国英,任瑞征等编著,算法设计与分析(第2版),清华大学出版社,2009年1月,第200-202页。

提示:这是一个利用回溯算法的迷宫搜索类型问题,可参考类似问题的已有解法。

 

#include "iostream"
#include "vector"
using namespace std;

#define M 4 
#define N 4

typedef struct {
	int i;
	int j;
	int value;
}Elem;

 int Apple[M][N] = {7,0,4,18,4,0,1,1,15,7,11,-1,0,12,-2,0};

vector<Elem> MaxPath;
int MaxPathLength = 0;

void FindPath(vector<Elem> Path, int PathLen, int i, int j) {

	if(Apple[i][j] == -2) {
		if(PathLen > MaxPathLength) {
			Elem e;
			e.i = i;
			e.j = j;
			e.value = Apple[i][j];
			Path.push_back(e);
			MaxPath = Path;
			MaxPathLength = PathLen + 1;
		}

	}
	else {
		if(i>=0 && j>=0 && i<M && j<N && Apple[i][j] != 0) {
			Elem e;
			e.i = i;
			e.j = j;
			e.value = Apple[i][j];
			Path.push_back(e);
			PathLen += e.value;
			Apple[i][j] = 0;
			FindPath(Path,PathLen,i+1,j);
			FindPath(Path,PathLen,i-1,j);
			FindPath(Path,PathLen,i,j+1);
			FindPath(Path,PathLen,i,j-1);
			Apple[i][j] = e.value;
		}
	}
}

int main() {
	vector<Elem> Path;
	int PathLen = 0;
	int Entrance_i = 0;
	int Entrance_j = 0;
	for(int i=0;i<M;i++)
		for(int j=0;j<N;j++)
			if(Apple[i][j] == -1){
				Entrance_i = i;
				Entrance_j = j;
				break;
			}
	FindPath(Path,PathLen,Entrance_i,Entrance_j);
	for(vector<Elem>::iterator iter = MaxPath.begin();
			iter != MaxPath.end();++iter)
		cout<<"("<<(*iter).i<<","<<(*iter).j<<")"<<' ';
	cout<<endl;
	cout<<"The count of Apple is: "<<MaxPathLength<<"."<<endl;
		return 0;
}

下面是对回溯算法的相关应用:

1:八皇后问题

#include <iostream.h>
#include <math.h>

#define M 8
int Queen[M];

	int count = 0;
void PutQueen(int k) {
	if(k<M) {
		for(int i=0;i<M;i++) {
			Queen[k] = i;
			bool IsValid = true;
			for(int j=0;j<k;j++) {
				if(Queen[k] == Queen[j] || abs(Queen[k]-Queen[j]) == k-j)
					IsValid = false;
			}
			if(IsValid) {
				if(k == M-1) {
				count++;
				cout<<"The count: "<<count<<endl;
				for(int m=0;m<M;m++)
					cout<<Queen[m];
				cout<<endl;			
				}
		    	else
				PutQueen(k+1);
			}
		}
	}
}
int main() {

	PutQueen(0);
	cout<<"The count: "<<count<<endl;
	return 0;
}



2:桥本分数式

#include "iostream"
using namespace std;

int a[10];
int s = 0;

void Put(int k) {
	int m1,m2,m3,g,i,j;
	if(k <= 9) {
		for(i=1; i<=9; i++) {
			a[k] = i;
			g = 0;
			for(j=1; j<k; j++)
				if(a[j] == a[k])
					g=1;
			if(g == 0) {
				if(k==9 && a[1]<a[4]) {
					m1=a[2]*10+a[3];
					m2=a[5]*10+a[6];
					m3=a[8]*10+a[9];
					if(a[1]*m2*m3+a[4]*m1*m3==a[7]*m1*m2) {
						s++;
						cout<<a[1]<<"/"<<a[2]<<a[3]
							<<" + "
							<<a[4]<<"/"<<a[5]<<a[6]
							<<" = "
							<<a[7]<<"/"<<a[8]<<a[9]<<endl;
					}
				}
				else 
					Put(k+1);		
			}
		}
	}
}
int main() {
	Put(1);
	cout<<s;
	return 0;
}


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值