分治算法初步

hdu1007

http://acm.hdu.edu.cn/showproblem.php?pid=1007

解题关键:分治算法求解,注意学习分治算法的写法

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<iostream>
 7 #define inf 0x3f3f3f3f
 8 using namespace std;
 9 typedef long long ll;
10 struct point{
11     double x,y;
12 }p[100002],tmp[100002];
13 double dis(point &a,point &b){
14     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
15 }
16 bool cmp1(point &a,point &b){
17     return a.x<b.x;
18 }
19 bool cmp2(point &a,point &b){
20     return a.y<b.y;
21 }
22 double closet(int l,int r){
23     if(l==r) return inf;
24     if(l+1==r) return dis(p[l],p[r]);
25     int mid=(l+r)>>1;
26     double d1,d2,d;
27     d1=closet(l, mid),d2=closet(mid+1, r);
28     d=min(d1,d2);
29     int k=0;
30     for(int i=l;i<=r;i++){
31         if(fabs(p[i].x-p[mid].x)<mid) tmp[k++]=p[i];
32     }
33     sort(tmp, tmp+k,cmp2);
34     for(int i=0;i<k-1;i++){
35         for(int j=i+1;j<k;j++){
36             if(fabs(tmp[j].y-tmp[i].y)>=d) break;
37             d=min(d,dis(tmp[i],tmp[j]));
38         }
39     }
40     return d;
41 }
42
43
44 int main(){
45     int n;
46     while(scanf("%d",&n)!=EOF){
47         if(!n) continue;
48         for(int i=0;i<n;i++){
49             scanf("%lf%lf",&p[i].x,&p[i].y);
50         }
51         sort(p,p+n,cmp1);
52         double ans=closet(0, n-1);
53         printf("%.2f\n",ans/2);
54     }
55
56 }

树上分治和数列分治待补。

时间: 2024-08-16 17:51:55

分治算法初步的相关文章

【算法】2 由股票收益问题再看分治算法和递归式

回顾分治算法 分治算法的英文名叫做"divide and conquer",它的意思是将一块领土分解为若干块小部分,然后一块块的占领征服,让它们彼此异化.这就是英国人的军事策略,但我们今天要看的是算法. 如前所述,分治算法有3步,在上一篇中已有介绍,它们对应的英文名分别是:divide.conquer.combine. 接下来我们通过多个小算法来深化对分治算法的理解. 二分查找算法 问题描述:在已排序的数组A中查找是否存在数字n. 1)分:取得数组A中的中间数,并将其与n比较 2)治:

【算法基础】由股票收益问题再看分治算法和递归式

最大子数组问题 最近有一个比较火的话题,股票,那么这一篇就由此引入来进一步学习分治算法.在上一篇博客中已经对插入排序和分治算法做了初步的介绍,建议在看一篇前先看看:[算法基础]由插入排序看如何分析和设计算法 当然了,这篇博客主要用来介绍算法而非讲解股票,所以这里已经有了股票的价格,如下所示. 天 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 股票价格 50 57 65 75 67 60 54 51 48 44 47 43 56 64 71 65 6

分治算法(Divide and Conquer)

分治算法 在计算机科学中,分治法是建基于多项分支递归的一种很重要的算法范式.字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并. 分治法所能解决的问题一般具有以下几个特征: 问题的规模缩小到一定的程度就可以容易地解决 问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质 利用该问题分解出的子问题的解可以合并为该问题的解 该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问

分治算法

分治算法即将一个问题划分成多个子问题求解,最后的结果就是几个子问题的合集,通常图形类的算法,尤其是2的几次方数组问题可以优先考虑. 汉诺塔和二分搜索都是分治算法的思想,个人觉得最好体现分治算法的demo是棋盘覆盖问题,代码如下: #include <stdio.h> #include <stdlib.h> #define SIZE 4 static int title = 1; //title表示L型骨牌的编号 static int board[SIZE][SIZE]; /** *

自我练习 - 分治算法

2017-08-21 19:38:32 writer:pprp /* theme:第一章 - 分治算法 name:魔法石的诱惑 writer:pprp description:给你Q(0<=Q<=10^8),问你最小的自然数N使N的阶乘在十进制下包含Q个0 input:Q output: N date:Monday 2017/8/21 */ #include <bits/stdc++.h> using namespace std; const int maxn = 50000000

分治算法(二)

大家都知道选择排序和冒泡排序,这两个排序都是双重for循环,时间复杂度为O(n^2),显然效率都是比较低的,而运用分治思想的归并排序和快速排序会更高效一些. 1.归并排序 1)原理:假设初始序列含有n个记录,则可以看成是n个有序子序列,每个子序列的长度为1,然后两两归并,得到[n/2]([x]表示不小于x的最小整数)个长度为2或1的有序子序列:再两两归并,--,如此重复,直至得到一个长度为n的有序序列为止,这种排序方法成为2路归并排序.(摘自<大话数据结构>) 可见其运用了典型的分治思想,①分

基于分治算法的归并排序

#include <stdio.h> #include <math.h> void main() { int array[] = {1,212,35,1,456,12376,167,12,7523,71,634}; mergeSort(array, 0, 10); for(int i = 0; i < 11; i++ ) { printf("%d\n", array[i]); } } void mergeSort(int* array, int start

五大算法之分治算法

一.基本思想 当我们求解某些问题时,由于这些问题要处理的数据相当多,或求解过程相当复杂,使得直接求解法在时间上相当长,或者根本无法直接求出.对于这类问题,我们往往先把它分解成几个子问题,找到求出这几个子问题的解法后,再找到合适的方法,把它们组合成求整个问题的解法.如果这些子问题还较大,难以解决,可以再把它们分成几个更小的子问题,以此类推,直至可以直接求出解为止.这就是分治策略的基本思想. 二.二分法 利用分治策略求解时,所需时间取决于分解后子问题的个数.子问题的规模大小等因素,而二分法,由于其划

再回首--分治算法

谈起分治算法,首先从字面意思理解:就是将一个问题划分成多个较小的问题的算法.其实正应题目的意思.其基本设计思想就是:将一个难以直接解决的大问题分解成一些规模较小的相同问题以便各个击破,分而治之. 设计步骤:1)分解:分解成若干子问题 2)求解:求解个子问题 3)合并:将子解合并成原问题的解. 在自考的时候,我们遇到的二路归并算法就属于一种分治法.当然,要学会算法,就要找到其核心,抓住其核心了,我们也就明白算法是怎么回事了.下面我们通过二路归并算法找到其核心. 例子:给出一列数:4,2,8,3.利