四色问题(C语言)

目录

问题描述

 解决思路

染色思路

 代码示例


问题描述

四色定理(世界近代三大数学难题之一),又称四色猜想、四色问题,是世界三大数学猜想之一。四色定理的本质正是二维平面的固有属性,即平面内不可出现交叉而没有公共点的两条直线。用数学语言表示即“将平面任意地细分为不相重叠的区域,每一个区域总可以用1234这四个数字之一来标记而不会使相邻的两个区域得到相同的数字。”这里所指的相邻区域是指有一整段边界是公共的。如果两个区域只相遇于一点或有限多点就不叫相邻的。因为用相同的颜色给它们着色不会引起混淆。很多人证明了二维平面内无法构造五个或五个以上两两相连区域,但却没有将其上升到逻辑关系和二维固有属性的层面,以致出现了很多伪反例。

 解决思路

首先考虑的是如何将地图存储,我们只 关心图与图之间的相邻关系,所以我们 选择图的邻接矩阵来存储图,如果i区域 和j区域相邻,那么我们就对[i][j]和[j][i] 赋值为1,不相邻的区域赋值为0。

则该图用领接矩阵表示为

                                                        { 0, 1, 1, 1, 1, 1,           

                                                          1, 0, 1, 0, 1, 0,           

                                                          1, 1, 0, 1, 1, 1,           

                                                          1, 0, 1, 0, 0, 1,           

                                                          1, 1, 1, 0, 0, 1,           

                                                          1, 0, 1, 1, 1,0 }

染色思路

每一个区域的染色用0,1,2,3逐个尝 试,如果染色与相邻区域的颜色不同, 就将此颜色入栈。如果染色与相邻区域的 颜色相同,则尝试下一个颜色。如果尝试 到最后仍然重色,则退栈至上一个区域, 看此区域是否可染其他颜色,若能,则换 色后继续对下一区域染色,若不能,则再 退栈至上一区域,看是否能染其他颜色… 如此循环,直至所有区域染色成功。

 代码示例

#include<stdio.h>
int detection(int map[6][6], int stack[], int top)                      //检查是否撞色 
{
	int j;
	for (j = 0; j < top; j++)
	{
		if (map[j][top] == 1 && stack[top] == stack[j])//如果相邻且颜色相同则返回1,不同返回0
		{
			return 1;
		}
	}
	return 0;
}
int main()
{
	char *colorarr[4] = { "红色","绿色","蓝色","黄色" };//颜色数组
	int num;
	printf("请输入共几块地:");
	scanf("%d",&num);
	
	int arr[num][num];
	int i,j,k;
	for(i=0;i<num;i++)
	{
		printf("请输入第%d块地与其余是否相邻(1表示是,0表示否):",(i+1));
		for(j=0;j<num;j++)
		{
			scanf("%d",&arr[i][j]);
		}
	} 

	int stack[num];//定义栈
	int top = 0;
	
	int color = 0;//颜色0

	stack[top] = color;//第一块区域染色,颜色0入栈
	top++;
	
	while (top < num)
	{
		while (color < 4&&top < num)
		{
			stack[top] = color;//由0开始染色
			while (detection(arr, stack, top))//检验是撞色
			{
				color++;//如果撞色则尝试下一个颜色
				stack[top] = color;
			}
			if (color < 4)//看看颜色是否符合要求
			{
				top++;//符合要求就将颜色入栈
				color = 0;//颜色要重置为0
			}
		}		
		if (color >= 4)//颜色不符合条件就要开始回溯
		{
			top--;
			color = stack[top] + 1;	//在原有颜色基础上尝试下一种颜色	
		}
	}	
	for (k = 0; k < num; k++)
	{
		printf("第%d块地的颜色是%s\n", k+1, colorarr[stack[k]]);
	}
	return 0;
}

运行示例

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_我想睡觉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值