分治法的简单应用 | Koch Curve | 科赫曲线 | C/C++实现

问题描述

请编写一个程序,输入整数n,输出科赫曲线的顶点坐标,该科赫曲线由深度为n的递归调用画出。

科赫曲线是一种广为人知的不规则碎片形。不规则碎片形是具有递归结构的图形,可以通过下述递归函数的调用画出。

1.将给定线段(p1, p2)三等分。
2.以三等分点s, t为顶点作出正三角形(s, u, t)。
3.对线段(p1, s), 线段(s, u), 线段(u,t), 线段(t, p2)递归地重复进行上述操作,设端点为(0, 0), (100, 0)。

输入: 输入1个整数n。
输出: 输出科赫曲线各顶点的坐标(x, y),每个点的坐标占一行。输出时请从端点(0,0)开始,沿连续线段顺次输出顶点坐标,到端点(100, 0)结束。输出误差不得超过0.0001。
限制: 0≤n≤6

输入示例

1

输出示例

0.00000000 0.00000000
33.33333333 33.33333333
50.00000000 28.86751346
66.66666667 0.00000000
100.00000000 0.00000000

讲解

Koch Curve科赫曲线
koch函数包含3个参数,分别是递归深度d,以及线段的两个端点p1,p2。这个递归函数首先会求出线段p1, p2的三等分点s, t, 然后求能够使得线段su, ut, ts组成正三角形的点u。接下来,函数会顺次进行以下处理,从而描绘成线段。

1.对线段p1s递归调用koch,输出s的坐标。
2.对线段su递归调用koch,输出u的坐标。
3.对线段ut递归调用koch,输出t的坐标。
4.对线段tp2递归调用koch。

u的坐标可通过矢量运算求得。首先,s与t的坐标可通过以下算式求出。

s.x = (2 * p1.x + 1 * p2.x)/3
s.y = (2 * p1.y + 1 * p2.y)/3
t.x = (1 * p1.x + 2 * p2.x)/3
t.y = (1 * p1.y + 2 * p2.y)/3

以点s为起点,将点t逆时针旋转60°,即可得到点u。我们在这里采用旋转矩阵(一种以原点为中心进行旋转变换时常用的矩阵),通过下面的式子求出点u。

u.x = (t.x - s.x) * cos60° - (t.y - s.y) * sin60° + s.x
u.y = (t.x - s.x) * sin60° + (t.y - s.y) * cos60° + s.y

只要对初始状态的端点p1,p2调用koch,我们就可以按顺序输出从p1到p2的所有顶点。

AC代码如下

#include<stdio.h>
#include<math.h>
#define M_PI 3.14159265358979323846
struct Point{double x, y; };

void koch(int n, Point a, Point b){
	if(n == 0) return;
	
	Point s, t, u;
	double th = M_PI * 60.0/180.0;//将单位从度变为弧度
	
	s.x = (2.0 * a.x + 1.0 * b.x) / 3.0;
	s.y = (2.0 * a.y + 1.0 * b.y) / 3.0;
	t.x = (1.0 * a.x + 2.0 * b.x) / 3.0;
	t.y = (1.0 * a.y + 2.0 * b.y) / 3.0;
	u.x = (t.x - s.x) * cos(th) - (t.y - s.y) * sin(th) + s.x;
	u.y = (t.x - s.x) * sin(th) - (t.y - s.y) * cos(th) + s.y;
	
	koch(n - 1, a, s);
	printf("%.8f %.8f\n", s.x, s.y);
	koch(n - 1, s, u);
	printf("%.8f %.8f\n", u.x, u.y);
	koch(n - 1, u, t);
	printf("%.8f %.8f\n", t.x, t.y);
	koch(n - 1, t, b);
}

int main(){
	Point a, b;
	int n;
	
	scanf("%d", &n);
	
	a.x = 0;
	a.y = 0;
	b.x = 100;
	b.y = 0;
	
	printf("%.8f %.8f\n", a.x, a.y);
	koch(n, a, b);
	printf("%.8f %.8f\n", b.x, b.y);
	
	return 0;
}
  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
二分搜索是一种常见的查找算,利用它可以在有序数组中快速查找某个元素。然而,如果数组过大,一次性搜索整个数组可能会非常耗时。这时,可以使用分治将大问题分解成小问题进行处理,进而提升算效率。 下面是使用分治解决二分搜索的c/c++代码: ```c++ #include <iostream> #include <vector> using namespace std; int binarySearch(vector<int>& nums, int target, int left, int right) { if (left > right) { return -1; } int mid = left + (right - left) / 2; if (nums[mid] == target) { return mid; } else if (nums[mid] > target) { return binarySearch(nums, target, left, mid - 1); } else { return binarySearch(nums, target, mid + 1, right); } } int main() { vector<int> nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int target = 8; int index = binarySearch(nums, target, 0, nums.size() - 1); if (index == -1) { cout << "Target not found" << endl; } else { cout << "Target found at index " << index << endl; } return 0; } ``` 在这段代码中,我们定义了一个名为binarySearch的函数,它接受一个有序数组、目标值、数组的左右边界作为参数,返回目标值在数组中的下标。函数首先判断左右边界是否交叉,如果是,则说明数组中没有目标值,返回-1。否则,计算出数组中间元素的下标mid,如果mid对应的值等于目标值,则直接返回mid,否则根据mid对应的值与目标值的大小关系,将搜索范围缩小到左半部分或右半部分,递归调用函数。最终,如果找到目标值,则返回其下标,否则返回-1。 在主函数中,我们定义了一个有序数组和一个目标值,调用binarySearch函数查找目标值在数组中的下标,并输出结果。 使用分治解决二分搜索可以将大问题分解成小问题,提升算效率,但需要注意递归调用的终止条件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值