Missing number题解

  题目: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

代码如下:

// ConsoleApplication2.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include
#include
using namespace std;
#define N 20 
void printOutcome(int mark[],int length){   // 打印结果,没别的办法只有遍历
	for (int i = 0; i < length; i++){
		if (mark[i] == 0)
			cout << "Outcome is " << i + 1 << endl;
	}
}
bool isFull(int mark[], int length){
	int count = 0;
	for (int i = 0; i < length; i++){
		if (mark[i] == 0)
			count++;
	}
	if (count == 1)
		return true;
	else
		return false;
}
void getNum(string s, int mark[],int length){    //得到缺省值的函数
	if (s .empty()||isFull(mark,length)){    //如果为空,则结束递归,找到缺省值
		printOutcome(mark,length);
		exit(0);
	}
	if (!mark[s[0] - 49]){    //判断第一个数字是否被标记过
		string s2 = s.substr(1);
		mark[s[0] - 49] = 1;
		getNum(s2, mark, length);
		mark[s[0] - 49] = 0;   //不要忘记把标记的还原
	}
	if (s.length() >= 2 && 
		(s[0] - 48) * 10 + s[1] - 48 <= length 
		&& !(mark[(s[0] - 48) * 10 + s[1] - 49])){ //这里的情况有些复杂
		string s2 = s.substr(2);
		mark[(s[0] - 48) * 10 + s[1] - 49] = 1;
		getNum(s2, mark, length);
		mark[(s[0] - 48) * 10 + s[1] - 49] = 0;
	}
}
int _tmain(int argc, _TCHAR* argv[])
{
	string s = "81971112205101569183132414117";
	int mark[N] = { 0 };
	getNum(s, mark, N);
	return 0;
}


  主要思想是用回溯法,本题的难点就在于对字符串的分割,但这正好符合了回溯的思想——当一种分割不成功则采纳下一种方法,再加上适当的剪枝,时间复杂度可以接受(毕竟规模比较小)。

你可能感兴趣的:(Missing number题解)