递归与分治算法实验报告
来源:互联网 发布:qt5串口通信 源码 编辑:程序博客网 时间:2024/06/05 23:41
问题1:集合划分
算法思想:对于n个元素的集合,可以划分为由m个子集构成的集合,例如{{1,2}{3,4}}就是由2个子集构成的非空子集。假设f(n,m)表示将n个元素划分成由m个子集构成的集合的个数。那么1)若m == 1 , 则f(n,m)= 1 ;
2)若n == m ,则f(n,m)= 1 ;3)若不是上面两种情况则有下面两种情况构成:3.1)向n-1个元素划分成的m个集合里面添加一个新的元素,则有m*f(n-1,m)种方法;3.2)向n-1个元素划分成的m-1个集合里添加一个由一个元素形成的独立的集合,则有f(n-1,m-1)种方法。
实验代码:
#include<iostream>
#include<fstream>
using namespace std ;
int jihehuafen( int n , int m )
{
if( m == 1 || n == m )
return 1 ;
else
return jihehuafen( n - 1 , m - 1 ) + m*jihehuafen( n - 1 , m ) ;
}
int main()
{
ifstream fin("C:/input.txt") ;
ofstream fout("C:/output.txt") ;
int N , M , num ;
fin >> N >> M ;
num = jihehuafen( N , M) ;
fout << num << endl ;
return 0 ;
}
问题2:输油管道
算法思想:由于主管道由东向西铺设。故主管道的铺设位置只和各油井的y坐标有关。要使主管道的y坐标最小,主管道的位置y坐标应是各个油井y坐标的中位数。先用快速排序法把各个油井的y坐标排序,然后取其中位数再计算各个油井y坐标与中位数差值的绝对值之和。
实验代码:
#include<iostream>
#include<fstream>
#include<cmath>
using namespace std ;
struct point//定义坐标结构体
{
int x ;
int y ;
};
//快速排序
void sort( point a[] , int size )
{
int i = 0 , j = size - 1 ;
int temp ;//用来保存作为基准的数
if( size >= 1 )
{
temp = a[0].y ;//用区间的第一个元素作为基准
while( i != j )//区间两端交替向中间扫描,知道i = j
{
while( i < j && a[j].y > temp )
j-- ; //从右向左扫描,找到第一个小于temp的a[j]
if( i < j )//表示找到a[j] ,把a[j] 赋给a[i]
{
a[i].y = a[j].y ;
i++ ;
}
while( i < j && a[i].y < temp )
i++ ;//从左向右扫描,找到第一个大于temp 的a[i]
if( i < j )//表示找到a[i],把a[i]赋给a[j]
{
a[j].y = a[i].y ;
j-- ;
}
}
a[i].y = temp ;
sort( a , i ) ;//对左递归
sort( a + i + 1 , size - i - 1 ) ;//对右递归
}
}
//取中位数
int madian( point *a , int size )
{
int num = size + 1 ;
return a[num/2 - 1].y ;
//return size%2 ? a[size>>1].y :( a[size>>1].y + a[ (size>>1) +1 ].y)>>1 ;
}
//计算最短路程
int lucheng( point *a , int size )
{
int mid = madian( a , size ) ;
int i , sum = 0 ;
for( i = 0 ; i < size ; i ++ )
{
sum +=abs( a[i].y - mid ) ;
}
return sum ;
}
int main()
{
ifstream fin( "C:/input.txt") ;
ofstream fout( "C:/output.txt") ;
int n ;
fin >> n ;
point *p = new point[n] ;
for( int i = 0 ; i < n ; i ++)
fin >> p[i].x >> p[i].y ;
sort( p , n ) ;
int minlen = lucheng( p , n) ;
fout << minlen << endl ;
return 0 ;
}
问题3:邮局选址问题
算法思想:同问题2
实验代码:
#include<iostream>
#include<fstream>
#include<cmath>
using namespace std ;
struct point
{
int x ;
int y ;
} ;
void sort_x( point *a , int size )
{
int temp ;
int i = 0 , j = size - 1 ;
if( size >= 1 )
{
temp = a[0].x ;//
while( i != j )
{
while( i < j && a[j].x > temp )
j-- ;
if( i < j )
{
a[i].x = a[j].x ;
i++ ;
}
while( i < j && a[i].x < temp )
i++ ;
if( i < j )
{
a[j].x = a[i].x ;
j-- ;
}
}
a[i].x = temp;
sort_x( a , i ) ;//
sort_x( a + i +1 , size - i - 1 ) ;//
}
}
void sort_y( point *a , int size )
{
int temp ;
int i = 0 , j = size - 1 ;
if( size >= 1 )
{
temp = a[0].y ;//
while( i < j )
{
while( i < j && a[j].y > temp )
j-- ;
if( i < j )
{
a[i].y = a[j].y ;
i++ ;
}
while( i < j && a[i].y < temp )
i++ ;
if( i < j )
{
a[j].y = a[i].y ;
j-- ;
}
}
a[i].y = temp;
sort_y( a , i ) ;//
sort_y( a + i +1 , size - i - 1 ) ;//
}
}
int madian_x( point *a , int size )
{
//int num = size + 1 ;
//return a[num/2 - 1].x ;
return size%2 ? a[size>>1].x :( a[size>>1].x + a[ (size>>1) +1 ].x)>>1 ;
}
int madian_y( point *a , int size )
{
int num = size + 1 ;
return a[num/2 - 1].y ;
//return size%2 ? a[size>>1].y :( a[size>>1].y + a[ (size>>1) +1 ].y)>>1 ;
}
int lucheng( point *a , int size )
{
int mid_x = madian_x( a , size ) ;
int mid_y = madian_y( a , size ) ;
int i , sum = 0 ;
for( i = 0 ; i < size ; i ++ )
{
sum += abs( a[i].y - mid_y ) + abs(a[i].x - mid_x ) ;
}
return sum ;
}
int main()
{
ifstream fin("C:/input.txt") ;
ofstream fout("C:/output.txt") ;
if( !fin )
{
cout<<"the file can't open!"<<endl;
return - 1 ;
}
int n ;
fin >> n ;
point *p = new point[n] ;
for( int i = 0 ; i < n ; i++ )
{
fin >> p[i].x >> p[i].y ;
}
sort_x( p , n ) ;
sort_y( p , n ) ;
int minlen = lucheng( p , n ) ;
fout << minlen << endl ;
delete []p ;
return 0 ;
}
问题4:整数因子分解问题
算法思想:采用递归的算法思想
实验代码:
#include<iostream>
#include<fstream>
using namespace std ;
int count = 0 ;
void yinzifenjie( int x )
{
if( x == 1 )
{
count++;
}
else
{
for( int i = 2 ; i <= x ; i++ )
{
if( x % i == 0 )
{
yinzifenjie(x/i);
}
}
}
}
int main()
{
ifstream fin("C:/input.txt") ;
ofstream fout("C:/output.txt") ;
if( !fin )
{
cout<<"the file can't open!"<<endl;
return - 1 ;
}
int x ;
fin >> x ;
yinzifenjie(x) ;
fout << count << endl ;
return 0 ;
}
问题5:众数问题
算法思想:首先利用快速排序将其数组排序,利用写的求中位数函数及其返回中位数起始点函数编写求众数。求众数函数思想是:找到中位数及其起始结束点,将众数初始化为中位数。判断起点左边的元素数是否大于中位数的重数,如果大于则向左递归找众数,再判断终点右边的元素数是否大于中位数的重数,如果大于则向右递归找众数。
实验代码:
#include<iostream>
#include<fstream>
using namespace std ;
//结构体用来保存众数的元素与重数
typedef struct
{
int element; //元素
int sum; //重数
}zhongshu;
//记录中位数的起始下标
typedef struct
{
int low;
int high;
}node;
//快排
zhongshu x ;
void sort( int a[] , int s , int t )//对a[s]到a[t]的元素排序
{
int i = s , j = t ;
int temp ;
if( s < t ) //区间里至少存在一个元素的情况
{
temp = a[s] ; //用区间的第一个元素做基准
while( i != j ) //区间两端交替向中间扫描,直到I=J
{
while( j > i && a[j] > temp )
j-- ; //从右向左扫描,找到第一个小于temp的a[j]
if( i < j ) //表示找到a[j],则a[i],a[j]交换
{
a[i] = a[j] ;
i++ ;
}
while( i < j && a[i] < temp )
i++ ; //从左向右扫描,找到第一个大于temp的a[i]
if( i < j ) //表示找到a[i],则a[i],a[j]交换
{
a[j] = a[i] ;
j-- ;
}
}
a[i] = temp ;
sort( a , s , i - 1 ) ; //对左递归
sort( a , i + 1 , t ) ; //对右递归
}
}
//中位数
int madian( int *a , int L , int R )
{
int num = L + R + 1 ;
return a[num/2] ;
}
//返回中位数的起始点终点
node spalit(int *a , int med , int L , int R )
{
node m ;
m.low = L ;
m.high = R ;
for( int i = 0 ; i <= R ; i++ )
{
if( med == a[i] )
{
m.low = i ;
break ;
}
}
for( int j = R ; j >= 0 ; j-- )
{
if( med == a[j] )
{
m.high = j ;
break ;
}
}
return m ;
}
//众数的重数求取
void mode( int *a , int L , int R )
{
if( L >= R )
return;//x.sum=0;
else
{
node n;
int temp = 0 ;
int med ;
med = madian( a , L , R ) ;
n = spalit( a , med , L , R );
temp = n.high - n.low + 1 ;
if( x.sum < temp )
{
x.element = med ;
x.sum = temp ;
}
if( n.low - L > temp )//
{
if( x.sum < temp )
{
x.element = med ;
x.sum = temp ;
}
mode(a , L , n.low - 1 ) ;
}
if( R - n.high > temp )
{
if( x.sum < temp )
{
x.element = med ;
x.sum=temp;
}
mode( a , n.high + 1 , R ) ;
}
}
}
int main()
{
x.sum = 0 ;
int n ;
int *a ;
ifstream fin("C:/input.txt");
ofstream fout("C:/output.tex");
if( !fin )
{
cout<<"the file can't open!"<<endl;
return - 1 ;
}
fin >> n ;
a = new int[n];
for( int i = 0 ; i < n ; i++)
{
fin >> a[i] ;
}
sort(a,0,n-1);
mode(a,0,n-1);
fout << x.element << endl << x.sum;
delete []a;
return 0 ;
}
- 递归与分治算法实验报告
- 分治与递归算法
- 递归与分治算法
- 算法--递归与分治策略
- 递归与分治算法初步学习
- 算法复习-递归与分治策略
- 算法之浅谈递归与分治
- 算法时间复杂度----分治与递归
- 【算法·递归与分治】二分查找
- 算法复习2:递归与分治策略
- 算法基础篇(3)------递归与分治
- 棋盘覆盖递归与分治算法
- 算法实验课(递归和分治法)
- java递归分治算法
- 算法设计与分析之递归与分治策略
- 递归与分治策略(一)---算法设计与分析
- 【算法设计与分析】递归与分治----2.4 排列问题
- 分治与递归(算法分析与设计)
- Eclipse Helios 插件安装(tomcat插件)
- Ubuntu图形界面最常见的图形化登录管理器
- scanf 使用总结
- device_register
- Android菜单详解(三)——SubMenu和IconMenu
- 递归与分治算法实验报告
- 全排列(数组)
- 设计原本——计算机科学巨匠Frederick P.Brooks的反思(精装版)
- 数据库访问表的几种方式
- 解决spring中使用声明事务java.lang.NoClassDefFoundError: org/aspectj/util/PartialOrder$PartialComparable.
- 25个增强iOS应用程序性能的提示和技巧(初级篇)
- 【rzxt】创建"常用程序"菜单 桌面一目了然
- 18岁的生日
- linux下tar.gz、tar、bz2、zip等解压缩、压缩命令小结