算法分析与设计编程题 递归与分治策略

棋盘覆盖

题目描述

请添加图片描述

请添加图片描述

解题代码

// para: 棋盘,行偏移,列偏移,特殊行,特殊列
void dividedCovering(vector<vector<int>>& chessBoard, int dr, int dc, int sr, int sc, int size) {
	if (size == 1) return;
	size /= 2; // 划分为四部分
	if (sr < dr + size && sc < dc + size) { // 特殊点位于左上部分
		divideCovering(chessBoard, dr, dc, sr, sc, size);
	}
	else {
		int nr = dr + size - 1, nc = dc + size - 1; // 新覆盖点
		chessBoard[nr][nc] = 1;
		divideCovering(chessBoard, dr, dc, nr, nc, size);
	}
	if (sr < dr + size && sc >= dc + size) { // 特殊点位于右上部分
		divideCovering(chessBoard, dr, dc + size, sr, sc, size);
	}
	else {
		int nr = dr + size - 1, nc = dc + size;
		chessBoard[nr][nc] = 1;
		divideCovering(chessBoard, dr, dc + size, nr, nc, size);
	}
	if (sr >= dr + size && sc < dc + size) { // 特殊点位于左下部分
		divideCovering(chessBoard, dr + size, dc, sr, sc, size);
	}
	else {
		int nr = dr + size, nc = dc + size - 1;
		chessBoard[nr][nc] = 1;
		divideCovering(chessBoard, dr + size, dc, nr, nc, size);
	}
	if (sr >= dr + size && sc >= dc + size) { // 特殊点位于右下部分
		divideCovering(chessBoard, dr + size, dc + size, sr, sc, size);
	}
	else {
		int nr = dr + size, nc = dc + size;
		chessBoard[nr][nc] = 1;
		divideCovering(chessBoard, dr + size, dc + size, nr, nc, size);
	}
}

void chessBoardCovering(vector<vector<int>>& chessBoard, int sr, int sc) {
	int n = chessBoard.size();
	divideCovering(chessBoard, 0, 0, sr, sc, n);
}

线性时间选择

题目描述

请添加图片描述

解题代码

int partition(vector<int>& nums, int left, int right) {
	int randIdx = rand() % (right - left + 1) + left; // 选取随机pivot
	swap(randIdx, nums[left]);
	int pivot = nums[left];
	while (left < right) {
		while (left < right && nums[right] >= pivot) --right;
		nums[left] = nums[right];
		while (left < right && nums[left] <= pivot) ++left;
		nums[right] = nums[left];
	}
	nums[left] = pivot;
	return left;
}

int dividedQuickSelect(vector<int>& nums, int left, int right, int k) {
	if (left >= right) return nums[left];
	int p = partition(nums, left, right); // 根据基准进行划分
	if (p == k) return nums[p]; // 划分基准正好为第k小的数
	else if (p > k) return divideQuickSelect(nums, left, p - 1, k); // 基准大于第k小
	else return divideQuickSelect(nums, p + 1, right, k); // 基准小于第k小
}

int quickSelect(vector<int>& nums, int k) {
	srand((unsigned)time(nullptr)); // 设定随机种子
	return divideQuickSelect(nums, 0, nums.size() - 1, k - 1);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值