Missing number

本文介绍了一种使用回溯法解决寻找缺失数字的问题。给定正整数n及由n-1个随机排列的数字组成的字符串s,通过合理的字符串划分找出1到n间缺失的数字。文章提供了详细的解题思路及C++代码实现。

一、题目

Given a positive integer n(n≤40), pick n-1 numbers randomly from 1 to n and concatenate them in random order as a string s, which means there is a missing number between 1 and n. Can you find the missing number?(Notice that in some cases the answer will not be unique, and in these cases you only need to find one valid answer.)

Examples:
 

  Input: 20
         81971112205101569183132414117
  Output: 16

二、题意

给定正整数n(n≤40),从1到n中随机选择n-1个数,并将它们以随机顺序连接为字符串s,这意味着在1和n之间有一个缺失的数字。你能找到那个缺失的数字吗?(请注意在某些情况下答案不唯一,此时你只需要找到一个有效的答案。)

三、解题思路

分支限界+回溯

归根结底本题时要找到字符串s的合理划分方法,因此可以用回溯法求解。假设字符串s长度为n,则当第i(i<n)个字符要么单独划分为一个数,要么和i+1一起划分为一个数;而第n个字符只能单独划分为一个数。因此可采用回溯法,向下一层左子树搜索的约束条件就是由第i个字符与第i+1个字符结合得到的数字落在1到n的范围内且之前未被划分出来,向下一层右子树搜索的约束条件就是由第i个字符单独形成的数字落在1到n的范围内且之前未被划分出来。如若当前字符为'0',说明之前的划分有误(因为'0'既不能和后一个字符结合,也不能单独成数),应该直接返回上一层。如何知道已经找到了正确的划分呢?只需要在搜索到叶子结点时检验是不是已经划分出n-1个数字即可。

因此划分和回溯就出来了:

1、当前字符下标等于n时,划分结束,判断当前是否找到了n-1个并输出

2、当前字符下标等于n-1时,只有单独划分的情况,递归调用(下标+1)

3、当前字符下标小于n-1时,有两种划分情况:

     1) 单独划分,递归调用(下标+1)

     2) 与后一个一起相组划分,递归调用(下标+2)

#include <iostream>
using namespace std;
int a[41] = {0};   // 记录这些数字有没有被找到 
bool flag = 0;     // 标记找到没,只找一个数 
void find(int findnum, string s, int index, int n){
	int length = s.length();
	if(flag == 1) return;
	if(index == length){
		// 判断有无符合要求的返回
		if(findnum == n-1){
			for(int i=1; i<=n; i++)
				if(a[i] == 0)
					cout<<i<<endl;
			flag = 1;
		}
	}
	if(index == length - 1){   // 最后一个数只能单独成数 
		// 单独成数
		if(a[s[index] - '0'] == 0 && s[index] != '0' && findnum<=n-1 && (s[index]-'0')<=n){
			a[s[index] - '0'] = 1;
			find(findnum+1, s, index+1, n);
			a[s[index] - '0'] = 0;  // 回溯 
		}
	}
	if(index < length - 1){
		// 单独成数
		if(a[s[index] - '0'] == 0 && s[index] != '0' && findnum<=n-1 && (s[index]-'0')<=n){
			a[s[index] - '0'] = 1;
			find(findnum+1, s, index+1, n);
			a[s[index] - '0'] = 0;  // 回溯 
		}
		// 与后一个成数
		if(s[index] != '0' && findnum<=n-1){
			int temp = (s[index] - '0')*10 + (s[index+1]-'0');
			if(temp<= n && a[temp] == 0){
				a[temp] = 1;
				find(findnum+1, s, index+2, n);
				a[temp] = 0;  // 回溯 
			}
		}
	}
}
int main (){
	int n;
	cin>>n;
	string s;
	cin>>s;
	find(0, s, 0, n);
	
	return 0;
} 

参考博文:https://blog.youkuaiyun.com/climber16/article/details/81604342

在 LaTeX 中遇到 `Missing number, treated as zero.` 错误通常表明编译器期望找到一个数字或长度值,但在相应位置上却发现了其他内容。此类错误在使用浮动体(如 `table` 或 `figure`)时较为常见,特别是在对表格、图形进行排版调整时。 ### 常见原因及解决方法 1. **在方括号中使用了非数字参数** - 在某些宏包或命令中,LaTeX 会将方括号中的内容解析为可选参数,例如 `[h]`、`[t]` 等用于指定浮动体位置的选项。如果在这些方括号中错误地使用了非数字或不被支持的内容,就会触发该错误。 - **解决方案**:确保所有可选参数均符合语法规范,必要时用大括号 `{}` 将特殊字符包裹起来以避免误解[^5]。 2. **在 `\begin{tabular}` 或 `\begin{array}` 中误用了方括号** - 如果在表格定义中直接使用了类似 `[x]` 的表达式而没有正确转义,LaTeX 可能会将其误认为是需要数值参数的命令。 - **解决方案**:在可能引起歧义的地方添加额外的大括号,例如将 `[x]` 改写为 `{[x]}`。 3. **与某些宏包冲突** - 某些情况下,使用了多个图形或表格相关的宏包(如 `subfigure`、`float`、`caption` 等),可能会导致命名冲突或参数处理异常。 - **解决方案**:检查更新宏包版本,尝试简化文档导言区引入的宏包数量,排查是否存在重复定义的问题[^4]。 4. **非法单位或缺少单位** - 当设置列宽、间距等参数时,如果没有正确指定单位(如 `pt`、`cm`),也可能引发此错误。 - **解决方案**:确保所有涉及尺寸设定的地方都带有合适的单位,例如 `\tabcolsep=0.4cm` 应保持格式一致[^2]。 5. **在浮动体外部使用浮动体命令** - 浮动体环境(如 `table`、`figure`)不能嵌套在某些不允许浮动的环境中(如 `framed`、`minipage` 等),否则会出现“Not in outer par mode”等错误,伴随 `Missing number` 提示。 - **解决方案**:移除浮动体标签 `[h]` 或改用非浮动表格/图形环境,或者使用 `H` 选项强制定位(需加载 `float` 宏包)[^1]。 6. **未正确结束数学模式** - 在数学环境中使用了不完整的命令结构,例如 `\begin{tabular}` 内部混用了数学符号但未正确闭合 `$...$`。 - **解决方案**:仔细检查所有数学公式是否完整闭合,避免跨行或跨列断开。 --- ### 示例修正代码 以下是一个修复后的 `table*` 环境示例: ```latex \usepackage{float} % 引入 float 宏包以使用 H 选项 \begin{table*}[H] \centering \caption{Quantitative results on NYUv2 dataset, the best performance is marked in bold} \label{tab6} \tabcolsep=0.4cm \begin{tabular}{cc} A & B \\ 1 & 2 \\ {[x]}^2 & 4 \end{tabular} \end{table*} ``` --- ### 总结 `Missing number, treated as zero.` 是一种典型的 LaTeX 编译错误,其根源往往在于参数格式不正确、宏包冲突或语法结构不完整。通过逐一排查上述几种常见情况,可以有效定位解决问题。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值