有一道面试题如下:

运用四色定理,为N个局域举行配色,颜色为1、2、3、4四种,另有数组adj[][N],如adj[i][j]=1则表示i区域与j区域相邻,数组color[N],如color[i]=1,表示i区域的颜色为1号颜色。

网上给出的答案基本上都是:

#include <stdio.h>
#include <iostream>
using namespace std;
static int curcolor=0;
int pickaunic(int map[6][6],int color[6],int i)
{for (int j=0;j<6;j++){//如果区域i和区域j相邻并且当前要涂的颜色正好是区域j的颜色if (map[i][j]==1 && (curcolor%4) == color[j]) {//那么就换一种颜色,继续找下一个于区域i相邻的区域,如果颜色还冲突,那么再换颜色curcolor++; }}return (curcolor%4); //返回要涂的颜色
}void colored(int map[6][6],int color[6],int i)
{if (color[i]>0){return;}else{color[i] = pickaunic(map,color,i);for (int j=0;j<6;j++){if (map[i][j]==1){colored(map,color,j);}}}
}int main()
{     int map[6][6] = {{0, 0, 0, 1, 1, 0},{0, 0, 1, 1, 0, 1},{0, 1, 0, 1, 0, 0},{1, 1, 1, 0, 1, 1},{1, 0, 0, 1, 0, 1},{0, 1, 0, 1, 1, 0}}; int color[6]={-1,-1,-1,-1,-1,-1};colored(map,color,0);for( int i=0;i<6;++i )cout<<*(color+i)<<endl;return 0;
}

使用该代码运行后得出的结果,也就是打印color数组的结果为:

从结果中可以看出,区域2和区域4的颜色均为颜色1,但从map矩阵我们可以看出,区域2和区域4是邻居,也就是说区域2和区域4的颜色不能相同,因此可以看出该解法有问题。

首先,我们将colored函数中colored[i]>0改为colored[i]>=0,没有必要将条件设为大于0,设为大于0,得到的颜色值为1~4,而设为大于等于0的话,得到的颜色值为0~3,这样会减少一些赋值。当将colored[i]>0改为colored[i]>=0时,结果如下:

在此次结果中,我们可以看出区域1和区域5的颜色均为颜色0,但从map矩阵我们可以看出,区域1和区域5是邻居,也就是说区域1和区域5的颜色不能相同,因此可以看出该解法仍然是有问题的,这也在意料之中,因为并未改变算法的实质。

让我们分析一下算法的问题所在:

当要给区域5着色时,curcolor的值为3,区域1、4、2、3、6的颜色值分别为0、1、2、3、3,因为区域5是与区域1、4、6紧邻的,在pickaunic函数中先后将区域5与区域1、4、6进行如下if的判断:
if (map[i][j]==1 && (curcolor%4) == color[j]) //如果区域i和区域j相邻并且当前要涂的颜色正好是区域j的颜色
{
            curcolor++; //那么就换一种颜色,继续找下一个于区域i相邻的区域,如果颜色还冲突,那么再换颜色
}

当将curcolor与区域1的color=0比较时,两者不等,继续,当将curcolor与区域4的color=1比较时,仍不等,继续,当将curcolor与区域6的color=3比较时,相等,因此curcolor变为4,所以当返回return(curcolor%4);时,返回的是0,也就是说区域5的颜色值与区域1的颜色值相同了,均为颜色0;这就是问题的所在。

问题解决:

解决后的代码如下:

#include <stdio.h>
#include <iostream>
#include <map>
using namespace std;
int pickaunic(int map[6][6],int color[6],int i)
{std::map<int, bool> colors;for( int i=0;i<4;++i ){colors[i]=false;}for (int j=0;j<6;j++){if (map[i][j]==1&&color[j]>=0) {colors[ color[j] ]=true;}}for( int i=0;i<4;++i ){if( !colors[i] )return i;}return -1; //返回要涂的颜色
}void colored( int map[6][6],int color[6] )
{for( int i=0;i<6;++i ){color[i] = pickaunic(map,color,i);   }
}int main() {     int map[6][6] = {{0, 0, 0, 1, 1, 0},{0, 0, 1, 1, 0, 1},{0, 1, 0, 1, 0, 0},{1, 1, 1, 0, 1, 1},{1, 0, 0, 1, 0, 1},{0, 1, 0, 1, 1, 0}}; int color[6]={-1,-1,-1,-1,-1,-1};colored( map,color );for( int i=0;i<6;++i )cout<<*(color+i)<<endl;return 0;
}

上述代码运行结果为: 从图中可以看出,结果与map矩阵吻合的很好。
上述代码比较简单,不再解释。

四色定理涂色的解 --------------------- 对网上答案的纠正相关推荐

  1. 回溯问题一:地图涂色,四色定理证明

    **题意:**使用四种颜色对N块区域涂色,输出所有涂色方案 **解题思想:**使用图的遍历来做,每块区域抽象为图顶点,四种颜色,回溯遍历涂色 **回溯概念:**回溯与递归联系十分紧密,递归的过程包括正 ...

  2. 【算法•日更•第三十期】区间动态规划:洛谷P4170 [CQOI2007]涂色题解

    废话不多说,直接上题:  P4170 [CQOI2007]涂色 题目描述 假设你有一条长度为5的木版,初始时没有涂过任何颜色.你希望把它的5个单位长度分别涂上红.绿.蓝.绿.红色,用一个长度为5的字符 ...

  3. 涂色游戏color(【CCF】NOI Online 能力测试2 提高组第一题 )

    子序列问题sequence([CCF]NOI Online能力测试2 提高组第二题 ) 游戏match([CCF]NOI Online能力测试2 提高组第三题 ) 题目背景 1s 256M 题目描述 ...

  4. bzoj 2375: 疯狂的涂色

    2375: 疯狂的涂色 Time Limit: 5 Sec  Memory Limit: 128 MB Description 小t非常喜爱画画,但是他还是一个初学者.他最近费尽千辛万苦才拜到已仙逝的 ...

  5. 【BZOJ4817】【SDOI2017】树点涂色 [LCT][线段树]

    树点涂色 Time Limit: 10 Sec  Memory Limit: 128 MB [Submit][Status][Discuss] Description Bob有一棵n个点的有根树,其中 ...

  6. P1283 平板涂色

    P1283 平板涂色 题目描述 CE数码公司开发了一种名为自动涂色机(APM)的产品.它能用预定的颜色给一块由不同尺寸且互不覆盖的矩形构成的平板涂色. 为了涂色,APM需要使用一组刷子.每个刷子涂一种 ...

  7. 【数据结构与算法】之给Nx3网格图涂色的方案数的求解算法

    一.题目要求 你有一个 n x 3 的网格图 grid ,你需要用 红,黄,绿 三种颜色之一给每一个格子上色,且确保相邻格子颜色不同(也就是有相同水平边或者垂直边的格子颜色不同). 给你网格图的行数 ...

  8. [BZOJ1260][CQOI2007]涂色paint 区间dp

    1260: [CQOI2007]涂色paint Time Limit: 30 Sec  Memory Limit: 64 MB Submit: 1575  Solved: 955 [Submit][S ...

  9. LeetCode 276. 栅栏涂色(DP)

    文章目录 1. 题目 2. 解题 2.1 DP超时解 2.2 DP解 1. 题目 有 k 种颜色的涂料和一个包含 n 个栅栏柱的栅栏,每个栅栏柱可以用其中一种颜色进行上色. 你需要给所有栅栏柱上色,并 ...

最新文章

  1. 设计模式之简单工厂模式
  2. 网络工程师如何才能实现职位晋升
  3. 在将对象数组转换为json字符串
  4. Git GUI使用(二)
  5. python中一共有多少个关键字-Python中关键字有多少个?
  6. python花钱培训值吗-Python培训费用高不高?Python培训真的值得吗?
  7. 写在 Dubbo go 的第五年
  8. Python中for else注意事项
  9. 你知道SQL的这些错误用法吗?
  10. 动态内存分配到底为谁分配内存空间【浅谈动态内存的一个实例】
  11. java treemap value排序_【TreeMap】对Map按key和value分别排序
  12. mysql存储过程 try_mysql存储过程之异常处理篇
  13. 用html做工资查询登陆页面,薪资筛选页面.html
  14. 计算机网络综合实践任务书,计算机网络综合实任务书2012-11.doc
  15. BP神经网络用于预测
  16. arduino雨滴传感器和舵机控制
  17. SVN创建分支与合并(命令与界面)
  18. 【饭谈】自动化有三宝:工资高,福利好,代码和人总有一个能跑
  19. java星号心形代码_心形原创符号
  20. python 余弦定理_自己实现文本相似度算法(余弦定理)

热门文章

  1. Unicode编码的理解
  2. Android手机,charles安装证书时提示“键入凭据存储的密码”问题
  3. GowLom2 战神引擎传奇手游Mir200\Envir 目录主要配置文件中文翻译大全
  4. 晶振作为电子产品“心脏”关键部分,究竟是什么原理起到什么作用
  5. 732. 我的日程安排表 III
  6. 学生上课睡觉班主任怎么处理_“佛系教师”语录:小孩是别人的,成绩是校长的,饭碗是自己的...
  7. 如何计算地球球面上两个坐标点之间的弧度
  8. 泰雷兹高科技赋能全球最安全的电子护照之一,泰国公民咸受其益
  9. 如何在XP HOME版下设置共享文件夹及其权限?
  10. C#线程间操作无效:从不是创建控件“textbox1”的线程访问它