news 2026/4/16 17:07:53

UVa 10826 Hot or Cold

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
UVa 10826 Hot or Cold

题目描述

你和朋友在玩一个猜数字游戏。 朋友想一个111NNN之间的整数(包含两端)。 你可以无限次猜测,但希望用尽可能少的次数猜中。 朋友不会直接告诉你是否正确;唯一的反馈是:从第二次猜测开始,他会说“变热”或“变冷”,表示这次猜测比上一次更接近还是更远离目标数字(如果距离相同,他可能说任意一个)。 当你确定最后一次猜测正确时,告诉朋友,游戏胜利。

注意:每次猜测都必须是真正的猜测,符合所有已知信息。

问题:在最坏情况下,需要多少次猜测?

输入:多个测试用例,每行一个整数NNN1≤N≤3001 \le N \le 3001N300),以N=0N = 0N=0结束。

输出:对每个用例,输出最大猜测次数。

样例输入

75 75 0

样例输出

10 guess(es) required. 10 guess(es) required.

题目分析

这是一个最优最坏情况决策问题。我们需要设计一个策略,使得在最坏的反馈序列下,猜测次数最少。

关键约束:

  1. 第一次猜测没有“变热/变冷”反馈
  2. 第二次及以后的每次猜测都有反馈(相对于上一次)
  3. 反馈只告诉我们“更近”或“更远”,不直接给出距离

解题思路

1. 问题本质

每次猜测后,根据反馈可以排除一部分不可能的数字。我们需要选择猜测位置,使得无论反馈如何,剩余的可能区间尽可能小

2. 状态定义

f(l,r,last)f(l, r, last)f(l,r,last)表示:

  • 已知目标数字在区间[l,r][l, r][l,r]
  • 上一次猜测的数字是lastlastlast
  • 从当前状态开始,还需要的最少猜测次数(包括当前这次)

边界情况

  • 如果l=rl = rl=rlast=llast = llast=l,说明已经知道答案,只需111次确认
  • 如果l=rl = rl=rlast≠llast \neq llast=l,需要先猜lll,再确认,共222

3. 状态转移

假设当前猜测gggg∈[l,r]g \in [l, r]g[l,r]g≠lastg \neq lastg=last),根据反馈:

  • “变热”:目标离ggg比离lastlastlast更近,即∣x−g∣<∣x−last∣|x - g| < |x - last|xg<xlast
  • “变冷”:目标离ggg比离lastlastlast更远,即∣x−g∣>∣x−last∣|x - g| > |x - last|xg>xlast

我们需要计算两种反馈对应的新区间。

区间划分公式

解不等式∣x−g∣<∣x−last∣|x - g| < |x - last|xg<xlast

  1. 如果g<lastg < lastg<last
    目标xxxggglastlastlast的中点右侧,即x>g+last2x > \frac{g + last}{2}x>2g+last
    由于xxx是整数,分两种情况:

    • 如果g+lastg + lastg+last是偶数:x>g+last2x > \frac{g + last}{2}x>2g+lastx≥g+last2+1x \ge \frac{g + last}{2} + 1x2g+last+1
    • 如果g+lastg + lastg+last是奇数:x>g+last2x > \frac{g + last}{2}x>2g+lastx≥⌈g+last2⌉x \ge \lceil \frac{g + last}{2} \rceilx2g+last

    mid1=⌊g+last2⌋mid1 = \lfloor \frac{g + last}{2} \rfloormid1=2g+lastmid2=⌈g+last2⌉mid2 = \lceil \frac{g + last}{2} \rceilmid2=2g+last,则:

    • “变热”对应区间[max(l,mid2),r][max(l, mid2), r][max(l,mid2),r]
    • “变冷”对应区间[l,min(r,mid1)][l, min(r, mid1)][l,min(r,mid1)]
  2. 如果g>lastg > lastg>last:对称地:

    • “变热”对应区间[l,min(r,mid1)][l, min(r, mid1)][l,min(r,mid1)]
    • “变冷”对应区间[max(l,mid2),r][max(l, mid2), r][max(l,mid2),r]

4. 最优决策

对于每个状态(l,r,last)(l, r, last)(l,r,last),我们枚举所有可能的猜测ggg,计算:

  • hot=f(“变热”后的区间,g)hot = f(\text{“变热”后的区间}, g)hot=f(变热后的区间,g)
  • cold=f(“变冷”后的区间,g)cold = f(\text{“变冷”后的区间}, g)cold=f(变冷后的区间,g)

由于我们考虑最坏情况,所以这次猜测的代价是1+max⁡(hot,cold)1 + \max(hot, cold)1+max(hot,cold)
我们选择ggg使得这个代价最小:

f(l,r,last)=min⁡g∈[l,r],g≠last(1+max⁡(hot,cold)) f(l, r, last) = \min_{g \in [l, r], g \neq last} \left( 1 + \max(hot, cold) \right)f(l,r,last)=g[l,r],g=lastmin(1+max(hot,cold))

5. 状态压缩与记忆化

直接三维状态f(l,r,last)f(l, r, last)f(l,r,last)的状态数是O(N3)O(N^3)O(N3),太大。

关键观察:状态实际上只依赖于:

  1. 区间长度length=r−llength = r - llength=rl
  2. lastlastlast到区间边界的距离dist={last−lif last≥lr−lastif last<ldist = \begin{cases} last - l & \text{if } last \ge l \\ r - last & \text{if } last < l \end{cases}dist={lastlrlastiflastliflast<l

这是因为区间可以平移,相同长度和相对距离的状态是等价的。

因此我们使用二维数组dp[length][dist]dp[length][dist]dp[length][dist]进行记忆化,状态数降为O(N2)O(N^2)O(N2)

6. 初始猜测

第一次猜测没有lastlastlast,我们可以选择任意位置first∈[1,N]first \in [1, N]first[1,N]
最终答案是min⁡firstf(1,N,first)\min_{first} f(1, N, first)minfirstf(1,N,first)


算法复杂度

  • 状态数:O(N2)O(N^2)O(N2)
  • 每个状态计算:枚举O(N)O(N)O(N)个可能的ggg
  • 总复杂度:O(N3)O(N^3)O(N3),对于N≤300N \le 300N300可以接受

参考代码

// Hot or Cold// UVa ID: 10826// Verdict: Accepted// Submission Date: 2025-12-24// UVa Run Time: 0.050s//// 版权所有(C)2025,邱秋。metaphysis # yeah dot net#include<bits/stdc++.h>usingnamespacestd;constintMAXN=310,INF=0x3f3f3f3f;// dp[length][dist] 还需要的最小猜测次数intdp[MAXN][MAXN];// 计算在区间 [l, r] 内,已知上次猜测是 last 时,还需要的最小猜测次数intdfs(intl,intr,intlast){// 区间只剩一个数if(l==r)return(last==l)?1:2;// 压缩状态:length = 区间长度,dist = last到边界的距离intlength=r-l;intdist=(last>=l)?(last-l):(r-last);// 记忆化if(~dp[length][dist])returndp[length][dist];intbest=INF;// 枚举当前猜测点 gfor(intg=l;g<=r;++g){if(g==last)continue;// 不能重复猜同一个数// 计算分界点:|t-g| < |t-last| 等价于 t > midintmid1=(g+last)/2;// 向下取整intmid2=(g+last+1)/2;// 向上取整inthot=0;// "更热"情况intcold=0;// "更冷"情况if(g<last){// g 在 last 左边// "更热": 目标在右边 [max(l,mid2), r]if(mid2<=r)hot=dfs(max(l,mid2),r,g);// "更冷": 目标在左边 [l, min(r,mid1)]cold=dfs(l,min(r,mid1),g);}else{// g 在 last 右边// "更热": 目标在左边 [l, min(r,mid1)]if(mid1>=l)hot=dfs(l,min(r,mid1),g);// "更冷": 目标在右边 [max(l,mid2), r]cold=dfs(max(l,mid2),r,g);}// 最坏情况 + 当前这次猜测intworst=max(hot,cold)+1;best=min(best,worst);}returndp[length][dist]=best;}intmain(){// 初始化记忆化数组memset(dp,-1,sizeofdp);intn;while(cin>>n&&n){intanswer=INF;// 第一次猜测可以选择任意位置for(intfirst=1;first<=n;++first){answer=min(answer,dfs(1,n,first));}cout<<answer<<" guess(es) required."<<endl;}return0;}

总结

本题的难点在于:

  1. 理解“变热/变冷”反馈的信息含义
  2. 将问题转化为区间划分的动态规划
  3. 设计状态压缩减少复杂度

核心技巧:

  • 利用不等式推导区间划分公式
  • 通过对称性压缩状态
  • 采用min⁡max⁡\min \maxminmax决策应对最坏情况

这个解法充分利用了问题的数学性质,在O(N3)O(N^3)O(N3)时间内解决了N≤300N \le 300N300的问题,是一个优雅且高效的解决方案。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/15 20:31:02

【开题答辩全过程】以 高校跨校选课系统为例,包含答辩的问题和答案

个人简介一名14年经验的资深毕设内行人&#xff0c;语言擅长Java、php、微信小程序、Python、Golang、安卓Android等开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。感谢大家的…

作者头像 李华
网站建设 2026/4/16 4:35:42

Linux设备节点与平台总线-设备树

前提 前面的分析中我们知道,设备树文件最初的目的就是为了代替平台总线中的platform中的device的部份,那么设备树的dts 文件就必须在内核其中后传递给内核,那设备树是如何传递给内核? 编译流程 编译:DTC工具将dts 设备树文本文件编译为二进制dtb文件这种二进制文件是…

作者头像 李华
网站建设 2026/4/15 5:21:19

终极效率神器:一键实现代码与设计的完美融合

终极效率神器&#xff1a;一键实现代码与设计的完美融合 【免费下载链接】figma-html Builder.io for Figma: AI generation, export to code, import from web 项目地址: https://gitcode.com/gh_mirrors/fi/figma-html 还在为网页设计与前端开发之间的鸿沟而烦恼吗&am…

作者头像 李华
网站建设 2026/4/16 4:30:20

2025最新!自考必备8个AI论文工具测评与推荐

2025最新&#xff01;自考必备8个AI论文工具测评与推荐 2025年自考论文写作工具测评&#xff1a;高效提效的智能助手 随着人工智能技术的不断进步&#xff0c;越来越多的自考生开始借助AI工具提升论文写作效率。然而&#xff0c;面对市场上琳琅满目的论文辅助软件&#xff0c;如…

作者头像 李华
网站建设 2026/4/16 4:29:55

社区团购电商平台的设计与实现开题报告

社区团购电商平台的设计与实现开题报告 一、选题背景与研究意义&#xff08;一&#xff09;选题背景 随着移动互联网技术的飞速发展以及电子商务模式的不断创新&#xff0c;社区团购作为一种融合了“线上预订线下自提”的新型电商模式&#xff0c;凭借其低成本、高便捷性、强邻…

作者头像 李华