西南交大算法分析与设计实验8.4

 

在苦求资源无果后,自己编写,可能有bug,仅供参考

---------------------------------------------------------------------------------------------------------------------------------

#include<iostream>
using namespace std;
int col, row;
int NUMBER= 1;
struct heapnode {
	int choice;
	int level;
	int bound;
	int route[100];
};

heapnode heap[1000];
int heaplength = 0;
int level = 1;

int GetBound(heapnode temp);
int GetChoice(int** map, heapnode temp);
bool IsVisit(int** map, int x, heapnode temp);
void GetAns(int** map, int lbound);
void DeleteHeap();
void InsertHeap(heapnode temp);
bool Road(int** map, heapnode temp);

void GetAns(int **map,int lbound) {//lb=1,lb的意思是choice的最少应该是多少
	int travl[4] = { 1,-1,map[0][3 * col - 1],-map[0][3 * col - 1] };
//	for (int i = 0; i < 4; i++)cout << travl[i] << " ";
	for (int i = 1; i < NUMBER; i++) {
		heapnode temp;
		temp.level = 0;
		temp.route[0] = i;

		temp.choice = GetChoice(map, temp);
		temp.bound = GetBound(temp);
		if (temp.bound > lbound) {
			InsertHeap(temp);
		}
	}
	while (heaplength > 0) {
		heapnode temp = heap[1];
		DeleteHeap();
		if (temp.choice != 0) {
			for (int i = 0; i < 4; i++) {
				if ((temp.choice & (1<<i))) {
					heapnode node;
					node.level = temp.level + 1;
					for (int j = 0; j <= temp.level; j++) {
						node.route[j] = temp.route[j];
					}
					node.route[temp.level+1]=node.route[temp.level] + travl[i];
					node.choice = GetChoice(map,node);
					node.bound = GetBound(node);
					InsertHeap(node);
				}
			}
		}
		else {
			if (Road(map,temp)&&level < temp.level + 1) {
				level = temp.level + 1;
				
			}
		}
	}


}
//判断回路
bool Road(int** map, heapnode temp) {
	for (int i = 0; i < row; i++) {
		if (temp.route[temp.level] > map[i][3 * col - 1]) continue;
		for (int j = 0; j < 3 * col; j++) {
			if (temp.route[temp.level] == map[i][j]) {
				//上
				if (i - 1 >= 0) {
					if (  map[i - 1][j] == temp.route[0]) {
						return 1;

					}
					
				}

				if (i + 1 < row) {//下
					if (map[i + 1][j] == temp.route[0]) {
						return 1;

					}
					
				}
				if (j - 1 >= 0 &&  map[i][j - 1]== temp.route[0]) {//左
					return 1;

				}

				if (j + 1 < 3 * col&& map[i][j + 1]==temp.route[0]) {//右
					return 1;

				}


			}
		}
	}
	return 0;
}
//大顶堆
void InsertHeap(heapnode temp) {
	int i;
	for (i = heaplength + 1; i > 1; i /= 2) {
		if (temp.bound <= heap[i / 2].bound) break;
		else heap[i] = heap[i / 2];
	}
	heap[i] = temp;
	heaplength++;

}

void DeleteHeap() {
	int i;
	heapnode temp = heap[heaplength];
	heap[1] = temp;
	heap[heaplength].bound = -1;
	for (i = 2; i < heaplength; i *= 2) {
		if (heap[i].bound < heap[i+1].bound) i++;
		if (heap[i].bound < temp.bound) break;
		heap[i / 2] = heap[i];
	}
	i /= 2;
	heap[i] = temp;
	heaplength--;
}


int GetBound(heapnode temp) {
	int num = 0;
	for (int i = 0; i < 4; i++)
		if (temp.choice & (1 << i)) num++;
	return (temp.level * 4 + num);
}
bool IsVisit(int** map,int x,heapnode temp) {
	for (int i = 0; i <= temp.level; i++) {
		if (temp.route[i] == x) return 1;
	}
	return 0;
}
//choice 是一个4位2进制数,代表上下左右,每次计算后对choice左移,共移位3次
int GetChoice(int** map,heapnode temp) {
	int choice = 0;
	for (int i = 0; i < row; i++) {
		if (temp.route[temp.level] > map[i][3 * col - 1]) continue;
		for (int j = 0; j < 3 * col; j++) {
			if (temp.route[temp.level] == map[i][j]) {
				//上
				if (i - 1 >= 0) {
					if (map[i][j] % 2 == 1 && map[i][j+1] == -1 && !IsVisit(map,map[i-1][j],temp)) {
						choice++;
						
					}
					else if (map[i][j] % 2 == 0 && map[i][j - 1] == 0 && !IsVisit(map, map[i - 1][j], temp) ){
						choice++;
						
					}
				}
				choice = choice << 1;
				if (i + 1 < row) {//下
					if (map[i][j] % 2 == 1 && map[i][j+1] == 0 && !IsVisit(map, map[i + 1][j], temp)) {
						choice++;
						
					}
					else if (map[i][j] % 2 == 0 && map[i][j - 1] == -1 && !IsVisit(map, map[i + 1][j], temp)) {
						choice++;
						
					}
				}
				choice = choice << 1;
				if (j - 1 >= 0 && map[i][j] % 2 == 1 && !IsVisit(map, map[i][j -1 ], temp)) {//左
					choice++;
					
				}
				choice = choice << 1;
				if (j + 1 < 3 * col && map[i][j] % 2 == 0 && !IsVisit(map, map[i][j+1], temp)) {//右
					choice++;
					
				}
				//choice = choice << 1;
				return choice;
			}
		}
	}
	return choice;
}

int main() {
	cin >> row >> col;
	int** map = new int* [row];
	for (int i = 0; i < col; i++)
		map[i] = new int[3*col];

	
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < 3*col; j++) {
			if (j % 3 == 1) {
				char m;
				cin >> m;
				if (m == '/') map[i][j] = -1;
				else if (m == '\\') map[i][j] = 0;
			}
			else map[i][j] =  NUMBER++;
			


		}
	}
	//cout << NEMBER<<endl;
	GetAns(map, 1);





	/*for (int i = 0; i < row; i++) {
		for (int j = 0; j < 3 * col; j++) {
			cout << map[i][j] << " ";


		}
		cout << endl;
	}*/
	cout << level;

	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值