编程之美习题解答

习题1.2 中国象棋将帅问题

#include <iostream>

using namespace std;

void print()
{
	for (int i = 1; i <= 9; i++)
	{
		for (int j = 1; j <= 9; j++)
		{
			if (i % 3 != j % 3)
			{
				cout << "position: " << i << " " << j << endl;
			}
		}
	}
}

void main()
{
	print();
}

习题1.3 烙饼问题

比较简单,不过书上的递归用得很暴力!!!

习题 1.4 买书问题

哎,还是算了吧

习题1.5 快速找出机器故障

简单的异或,建立等价条件问题

习题1.6 饮料供货

这道题目是道很不错的习题,要详加分析

习题1.7 光影切割问题

逆序对问题,利用merge sort的思想即可在O(nlogn)的复杂度下解决

#include <iostream>
#include <algorithm>
#include <iterator>

using namespace std;

int array[] = {3, 9, 7, 4, 5, 2};
const int size = sizeof array / sizeof *array;
int temp[size];

int mergeCount(int *array, int leftIndex, int rightIndex)
{
	if (array == NULL || leftIndex < 0 || rightIndex < 0 || leftIndex > rightIndex)
		return -1;

	if (leftIndex == rightIndex)
		return 0;

	int midIndex = (leftIndex + rightIndex) / 2;
	int leftCount = mergeCount(array, leftIndex, midIndex);
	int rightCount = mergeCount(array, midIndex + 1, rightIndex);

	for (int i = leftIndex; i <= midIndex; i++)
		temp[i] = array[i];
	for (int i = midIndex + 1; i <= rightIndex; i++)
		temp[i] = array[i];

	int index1 = leftIndex;
	int destIndex = leftIndex;
	int index2 = midIndex + 1;
	int count = 0;
	while (index1 <= midIndex && index2 <= rightIndex)
	{
		if (temp[index1] > temp[index2])
		{
			count += midIndex - index1 + 1;
			array[destIndex++] = temp[index2++];
		}
		else
		{
			array[destIndex++] = temp[index1++];
		}
	}

	if (index1 == midIndex)
	{
		array[destIndex++] = temp[index2++];
	}
	else if (index2 == rightIndex)
	{
		array[destIndex++] = temp[index1++];
	}

	return leftCount + rightCount + count;
}

void main()
{
	int count = mergeCount(array, 0, size - 1);

	cout << "count = " << count << endl;
}


习题1.8 小飞的电梯调度算法

书上讲解得很详细了,而且很好理解~

习题1.9 高效率的安排见面会

这道题书上O(n^2)复杂度的解法没能看懂,不过O(nlogn)复杂度的解法非常好理解,这就够了

习题1.10 双线程高效下载

哎,对多线程编程没啥研究,悲情

习题1.11~1.13 NIM石头游戏

游戏类的编程还是算了吧

习题1.14 连连看游戏设计

算了吧

习题1.15 构造数独

算了吧

习题1.16 24点游戏

这是一道非常nice的习题,但是DP解法将会给出

习题1.17 俄罗斯方块游戏

还是算了吧

习题1.18 挖雷游戏

额,算了吧


2.1 求二进制中1的个数

经典题,百考不厌啊

2.2 不要被阶乘吓到

哎,还以为是计算阶乘呢,太弱了

2.3 寻找发帖水王

这道题解法本log早已收录

2.4 1的数目

很好的一道题,递归解和循环解都很出色

2.5 寻找最大的K个数

这道题的解法实在太多了,具体情况具体分析

2.6 精确表示浮点数

有意思的一道题

2.7 最大公约数问题

比较简单

2.8 找符合条件的整数

不能不说这道题很nb,稍后给出代码

2.9 斐波那契数列

解法有三种:一、二、三,灭哈哈哈

2.10 寻找数组的最大值和最小值

简单

2.11 寻找最近的点对

这也是一道非常好的习题,后面给出代码

2.12 快速寻找满足条件的两个数

简单吧

2.13 子数组的最大乘积

稍后给出代码

2.14 求数组的子数组之和的最大值

太经典了,DP解法和循环解法都让人印象深刻

这里要对扩展问题做深入讨论:

1. 若数组首尾相连

2. 返回最大子数组的位置

2.15 子数组之和的最大值

这又是一道非常好的习题,待会给出代码

2.16 求数组中最长递增序列子序列

很好的一道习题,O(nlogn)的复杂度解决掉才是王道

2.17 数组循环移位

比较简单

2.18 数组分割

除了回溯法解决以外,还真没想到特别好的办法

2.19 区间的重合判断

很好的习题,待会给出

2.20 程序理解和时间分析

看着办吧

2.21 只考加法的面试题


3.1 字符串移位包含的问题

题目不难

3.2 电话号码对应英语单词

不能不说这道题非常好

3.3 计算字符串的相似度

典型的DP问题

3.4 从无头单链表中删除结点

3.5 最短摘要的生成

3.6 编程判断两个链表是否相交

3.7 队列中取最大值操作问题

3.8 求二叉树中结点的最大距离

3.9 重建二叉树

3.10 分层遍历二叉树

#include <iostream>
#include <queue>

using namespace std;

struct Node
{
	Node(int i = 0, Node *l = NULL, Node *r = NULL) : data(i), left(l), right(r) {}
	int data;
	Node *left;
	Node *right;
};

Node* construct()
{
	Node *node8 = new Node(8);
	Node *node7 = new Node(7);
	Node *node6 = new Node(6);
	Node *node5 = new Node(5, node7, node8);
	Node *node4 = new Node(4);
	Node *node3 = new Node(3, NULL, node6);
	Node *node2 = new Node(2, node4, node5);
	Node *node1 = new Node(1, node2, node3);

	return node1;
}

void printLevel(Node *root)
{
	if (root == NULL)
		return;

	queue<Node*> qnodes;
	qnodes.push(root);
	int indexLeft = 0;
	int indexRight = 1;

	while (!qnodes.empty())
	{
		Node *node = qnodes.front();
		qnodes.pop();

		if (node->left != NULL)
			qnodes.push(node->left);
		if (node->right != NULL)
			qnodes.push(node->right);

		cout << node->data << " ";
		indexLeft++;
		if (indexLeft == indexRight)
		{
			cout << endl;
			indexRight = qnodes.size() + indexLeft;
		}
	}
}

void main()
{
	Node *root = construct();
	printLevel(root);
}


3.11 程序改错



4.1 金刚做飞机问题

不错的概率题

4.2 瓷砖覆盖地板问题

斐波那契问题

4.3 买票找零

很不错的题

4.4 点是否在三角形内

不错的题

4.5 磁带文件存放优化

4.6 桶中取黑白球

4.7 蚂蚁爬杆

4.8 三角形测试用例

4.9 数独知多少

4.10 数字哑谜和回文

1. 神奇的9位数

这道题关于如何整除太精彩了。。。

可以采用回溯法来解决,代码暂时不写

2. 人过大佛寺 * 我 = 寺佛大过人

这个题编码不难

4.11 扫雷游戏的概率

算了,不怎么玩扫雷

你可能感兴趣的:(编程)