回溯法

(1)图的染色问题

//图的染色
#include<iostream>
using namespace std;
const int N = 15;
int g[N][N];
int color[N];//记录没一个顶点的颜色
int res=0;
int flag = 0;
int isok(int k, int g[N][N]){//判断一个顶点是否满足要求
	for (int i = 1; i < k; i++){
		if (color[i] == color[k] && g[k][i] == 1){
			return 0;
		}
	}
	return 1;
}
int graphColor(int n, int m, int g[N][N]){
	int k = 1;//从顶点1开始出发
	memset(color, 0, sizeof(color));
	while (k >= 1){
		color[k] = color[k] + 1;//染上第一种颜色
		while (color[k] <= m){
			if (isok(k, g)){//如果color[k]颜色可以择,继续,否则循环试颜色
				break;
			}
			else{
				color[k] += 1;
			}
		}
		if (color[k] <= m&&k == n){//找到一种方式
			res++;
			flag = 1;
		}
		else if (color[k] <= m&&k < n){
			k += 1;
		}
		else{//回溯
			color[k] = 0;
			k -= 1;
		}
	}
	return flag;
}
int main(){
	int n, k, m;
	cin >> n >> k >> m;
	for (int i = 0; i < k; i++){
		int u, v;
		cin >> u >> v;
		g[u][v] = g[v][u] = 1;//无向连通图
	}
	if (graphColor(n, m, g)){
		cout << res << endl;
	}
	system("pause");
	return 0;
}

(2)桥本分数式

 

//桥本分数式
#include<iostream>
using namespace std;
int a[10];
int hashimoto(int i){//从第一各节点开始回溯
	a[1] = 1;
	int g;
	int cnt = 0;
	long long m1, m2, m3;
	while (1){
		g = 1;//对下一个数字是否重复进行标记
		for (int k = i - 1; k >= 0; --k){
			if (a[i] == a[k]){
				g = 0;
				break;
			}
		}
		if (g&&i == 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){
				cnt++;
			}
		}
		if (i < 9 && g == 1){
			++i;
			a[i] = 1;
			continue;
		}
		while (a[i] == 9 && i>1){//回溯
			i -= 1;
		}
		if (a[i] == 9 && i == 1){
			break;
		}
		else{
			a[i]++;
		}
	}
	return cnt;
}
int main(){
	int res=hashimoto(1);
	cout << res << endl;
	system("pause");
	return 0;
}

(3)高逐位整除数

 

posted @ 2020-10-18 00:43  goldstine  阅读(85)  评论(0)    收藏  举报