在之前一道最小生成树问题中遇到过,我按照以前的习惯把INF定义为10亿,然后初始化数组为最大值,然后输入连通的路+value,最后值仍然为INF的即为不通的。但是这里出问题了,INF定义为10亿的话,最后显示的数组的值是负的,最后改成0x3f3f3f3f终于解决了。

今天正好看到一篇相关的博客,故细细分析一下。

引用自:http://blog.csdn.net/bossup/article/details/9090277

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

如果问题中各数据的范围明确,那么无穷大的设定不是问题,在不明确的情况下,很多程序员都取0x7fffffff作为无穷大,因为这是32-bit int的最大值。如果这个无穷大只用于一般的比较(比如求最小值时min变量的初值),那么0x7fffffff确实是一个完美的选择,但是在更多的情况下,0x7fffffff并不是一个好的选择。

  1. 很多时候我们并不只是单纯拿无穷大来作比较,而是会运算后再做比较,例如在大部分最短路径算法中都会使用的松弛操作:
    if (d[u]+w[u][v]<d[v]) d[v]=d[u]+w[u][v];
    我们知道如果u,v之间没有边,那么w[u][v]=INF,如果我们的INF取0x7fffffff,那么d[u]+w[u][v]会溢出而变成负数,我们的松弛操作便出错了,更一般的说,0x7fffffff不能满足“无穷大加一个有穷的数依然是无穷大”,它变成了一个很小的负数。
  2. 除了要满足加上一个常数依然是无穷大之外,我们的常量还应该满足“无穷大加无穷大依然是无穷大”,至少两个无穷大相加不应该出现灾难性的错误,这一点上0x7fffffff依然不能满足我们。

所以我们需要一个更好的家伙来顶替0x7fffffff,最严谨的办法当然是对无穷大进行特别处理而不是找一个很大很大的常量来代替它(或者说模拟它),但是这样会让我们的编程过程变得很麻烦。在我读过的代码中,最精巧的无穷大常量取值是0x3f3f3f3f,我不知道是谁最先开始使用这个精妙的常量来做无穷大,不过我的确是从一位不认识的ACMer(ID:Staginner)的博客上学到的,他/她的很多代码中都使用了这个常量,于是我自己也尝试了一下,发现非常好用,而当我对这个常量做更深入的分析时,就发现它真的是非常精巧了。

  1. 0x3f3f3f3f的十进制是1061109567,也就是10^9级别的(和0x7fffffff一个数量级),而一般场合下的数据都是小于10^9的,所以它可以作为无穷大使用而不致出现数据大于无穷大的情形。
  2. 另一方面,由于一般的数据都不会大于10^9,所以当我们把无穷大加上一个数据时,它并不会溢出(这就满足了“无穷大加一个有穷的数依然是无穷大”),事实上0x3f3f3f3f+0x3f3f3f3f=2122219134,这非常大但却没有超过32-bit int的表示范围,所以0x3f3f3f3f还满足了我们“无穷大加无穷大还是无穷大”的需求。
  3. 最后,0x3f3f3f3f还能给我们带来一个意想不到的额外好处:如果我们想要将某个数组清零,我们通常会使用memset(a,0,sizeof(a))这样的代码来实现(方便而高效),但是当我们想将某个数组全部赋值为无穷大时(例如解决图论问题时邻接矩阵的初始化),就不能使用memset函数而得自己写循环了(写这些不重要的代码真的很痛苦),我们知道这是因为memset是按字节操作的,它能够对数组清零是因为0的每个字节都是0,现在好了,如果我们将无穷大设为0x3f3f3f3f,那么奇迹就发生了,0x3f3f3f3f的每个字节都是0x3f!所以要把一段内存全部置为无穷大,我们只需要memset(a,0x3f,sizeof(a))。

所以在通常的场合下,0x3f3f3f3f真的是一个非常棒的选择。

负无穷大用0xcfcfcfcf比较好。

关于0x3f3f3f3f(0x四个3f)相关推荐

  1. 【转帖】漫话C++0x(四) —- function, bind和lambda

    实在是觉得此文总是去翻感觉不太好.于是果断转过来了,想看原文的请戳:http://www.wuzesheng.com/?p=2032 本文是C++0x系列的第四篇,主要是内容是C++0x中新增的lam ...

  2. const int INF=0x3f3f3f3f;——ACM中的无穷大常量

    0x3f3f3f3f 0x开头的 是十六进制常数, 等于 十进制 1061109567 等于 二进制: 00111111 00111111 00111111 00111111 const int in ...

  3. 细节决定成败(竞赛错题经验总结)

    整理的算法模板合集: ACM模板 没有灵异事件,只有我是傻逼 图论的数组,涉及到点的开N,涉及到边的开M,开多了会TLE!根据题目要求设定, 凡是涉及到位运算的我都要累括号!!!位运算的优先级太糟糕了 ...

  4. cyyz: Day 4 网络流整理

    Day 4 网络流的理论性知识(算了..我自己都看不下去,还是整理些例题以后复习用吧qaq): 一.PPT(主要内容)   二.搜自度娘 定义: ①图论中的一种理论与方法,研究网络上的一类最优化问题 ...

  5. 北京尚学堂JAVASE课程

    北京尚学堂JAVASE课程 一.java历史-特点 1.计算机语言发展史 何为要发明计算机:为了进行科学计算,复杂的科学计算. 人类如何和计算机沟通,去分配任务. 通过计算机语言 实现 人类和计算机的 ...

  6. 算法题目——子序列和问题(poj-3061)(尺取法)

    题目链接:POJ-3061 题意:给定一个序列,使得其和大于或等于S,求最短的子序列长度. 问题分析: 1.首先序列都是正整数,当子序列和大于等于S时,已经没有必要再将右端点继续向右移动.因为再向右移 ...

  7. 数据库设计-航班管理系统

    设计目的: 随着社会发展的不断进步,旅游业的蓬勃发展,机票预订系统对人们的生活影响越来越大,为了实现航空公司以及旅游业的现代化管理,方便旅客,需要开发一个机票预订系统.该系统具有完整的存储,查询,核对 ...

  8. [小黑科技] 破解一个电控升降桌,并改造成语音控制(上)—— 模拟中间人与控制手柄交互...

    1.电路图破译 其电路板如下,是一个程序员专用升降桌的控制手柄: 简单看电路板,其原理图猜测是8路并转串,用来收集按键按下信息:两个串转8路并来驱动3个7段数码管: 2.破解其数码管显示原理 因此简单 ...

  9. 四种DCOM错误的区别,0x80080005 0x800706be 0x80010105 0x

    四种DCOM错误的区别 Differences between the following DCOM error 0x80080005 0x800706be 0x80010105 0x800706ba ...

最新文章

  1. 想要学好Go语言的必须知道的一个小技巧
  2. laravel + Vue 前后端分离 之 项目配置 - 开发环境
  3. 太阳的光和灯光有什么区别_墙体彩绘机UV(油性)和水性墨水怎么选择?有什么区别?...
  4. TVS 管性能及选型总结
  5. 操作系统短作业优先(SJF)调度算法
  6. 解析ThreadPoolExecutor类是如何保证线程池正确运行的
  7. 【Flink】Could not instantiate the executor. Make sure a planner module is on the classpath
  8. 2021年贵金属黄金会迎来大行情吗?
  9. 看雪CTF.TSRC 2018 团队赛 第六题 『追凶者也』 解题思路
  10. [BootStrap学习随笔] 起步、布局容器和栅格式布局
  11. python正则表达式模块re
  12. ExeScope辅助测试工具简介
  13. (八)flax Engine游戏引擎物理引擎——物理碰撞器
  14. 软件的高可用性、可扩展性和高性能
  15. 微观经济学案例分析(五)
  16. 3C数码行业供应商管理方案——与供应商结为“成长共同体”-数商云
  17. 80004005错误代码_win7系统出现错误代码0x80004005该如何解决
  18. oracle audit_actions,Oracle Audit 功能的使用和说明
  19. mysql 按照中文拼音首字母排序
  20. 永磁直驱风力发电机组并网仿真模型搭建

热门文章

  1. 微信获取临时素材接口
  2. android滑屏效果,Android使用ViewFlipper和GestrueDetector共同实现滑屏效果实例
  3. 大数据处理的数据从何而来?
  4. Matter协议特性解析(一) 支持非Matter协议,私有协议,Matter Bridge技术分析
  5. 2012版辅助开发工具包(ADT)新功能特性介绍及安装使用
  6. 常用的18大学术搜索引擎
  7. Kubernetes入门一:介绍及环境准备
  8. 四巫日来临本周硅铁、铁矿石领跌,铁矿石认沽最高31倍,钢厂利润回升2022.6.17
  9. 安全漏洞之SQL注入和shell注入
  10. 梯度下降计实例计算(二维)