算法分析与设计(李清勇)——分治
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
4-1 整数分解问题
#include <stdio.h>
#include <math.h>ﻫ#defineN100
int fenjie(int n);ﻫvoid main()
{ﻫint n; intcount;
printf("input a number\n");ﻫdoﻫ{
scanf("%d",&n);
}while(n<0);ﻫcount=fenjie(n);ﻫprintf("%d",count);ﻫ}
int fenjie(int n)ﻫ{ﻫint i;intk=0;int temp=0;int a[N];
for(i=2;i<sqrt(n);i++)ﻫ{if(n%i==0){ﻫa[k]=i;
k++;ﻫ}
}
for(i=0;i<k;i++)ﻫ{ for(j=0;i<k;i++){ﻫif(a[i]*a[j]==n)
printf("%d=%d*%d\n",n,a[i],a[j]);
temp++;ﻫ}ﻫ}ﻫreturntemp;
}
#include<stdlib.h>
#include<math.h>
void suanfa();void zdlch(intb);voidsurt(int k);
int N;//全局变量油井数
int s[100];//n个油井y轴坐标
int sumin;//输油管道最小长度
voidmain()
{int i;sumin=0;
scanf("%d",&N);
for(i=0;i<N;i++)
{scanf("%d",&s[i]);scanf("%d",&s[i]);}
suanfa();//调用关键算法函数
printf("%d\n",sumin);
}
voidsuanfa(){
if(N%2==0)//当油井数是偶数时
surt(N/2);else
surt((N+1)/2);//油井是奇数时
}
voidsurt(intk)//从大到小第k个数是b调用suanfa(b)函数求出路程
int j=0,b,l,m;int a=N;int i;
while(j!=k)
{b=s[0];
for(i=0;i<a;i++)
{if(s[i]>=b)
{
b=s[i];l=i ;
}
}
m=s[l];s[l]=s[a-1];s[a-1]=m;a--;j++;
}
zdlch(b);}
Void zdlch(intb)//求最小长度的总和{
int i;
for(i=0;i<N;i++)
sumin=sumin+(int)fabs(b-s[i]);}
4-4麦森书问题
#include <cstdio>#include <cstring>#include <cmath>#include <iostream>
#include <algorithm> using namespace std;
int f[505];//后500位数
void mul(int a)//乘以a{
int i,j,k,temp=0;
for(i=0;i<500;i++){
temp=temp+f[i]*a;
f[i]=temp%10;
temp=temp/10;
}
}
void sub(int x)//减x{
f[0]-=x;
int k=0;
while(k<500&&f[k]<0){
f[k]=f[k]+10;
f[k+1]--;
k++;
}
int main(){
int n;
while(scanf("%d",&n)!= EOF){
int i,j,k;
memset(f,0,sizeof(f));
f[0]=1;
//这里是分成2^10一段,那样就可以将乘法次数减少1/10
//若还想更快,可以再分大点,比如2^20这样,不过最好不要超过int
for(i=0;i<n/10;i++)mul(1024);
for(i=0,k=1;i<n%10;i++)k=k*2;//分段后剩余的部分
mul(k);
sub(1);
printf("%d\n",int(n*log(2)/log(10)+1));
//输出
for(i=0,k=499;i<10;i++) {
for(j=0;j<50;j++){
printf("%d",f[k]);
k--;
}
printf("\n");
}
}
}
4-5分治法,循环赛事日程表
#include "stdafx.h"#include <iostream> #include <math.h>
usingnamespace std;
voidTable(int k,int n,int **a);void input(int &k); voidoutput(int **a,intn);
int main(){
intk; input(k); intn=1;
ﻩ//n=2k(k>=1)个选手参加比赛
for(int i=1; i<=k; i++)
n *= 2;
//根据n动态分配二维数组a
int **a=newint *[n+1];
ﻩfor(int i=0;i<=n;i++){
ﻩa[i]= new int[n+1];}
Table(k,n,a);
ﻩcout<<"循环赛事日程表为:"<<endl;
output(a,n);
//释放空间
ﻩfor(int i=0;i<=n;i++)
{
delete[] a[i];
}
delete[]a;
return0;
}
void input(int&k){
cout<<"请输入k值:"<<endl;
cin>>k;
}
void output(int **a,int n){
ﻩfor(int i=1; i<=n;i++){
ﻩﻩfor(intj=1; j<=n;j++){
ﻩcout<<a[i][j]<<"";
ﻩ}
ﻩcout<<endl;
}
}
void Table(intk,int n,int **a){
ﻩfor(inti=1;i<=n; i++)
ﻩa[1][i]=i;//设置日程表第一行
ﻩint m = 1;//每次填充时,起始填充位置
for(ints=1; s<=k; s++)
ﻩn/=2;
ﻩfor(int t=1; t<=n; t++){
ﻩﻩfor(int i=m+1; i<=2*m; i++)//控制行{
ﻩfor(intj=m+1; j<=2*m; j++)//控制列{
a[i][j+(t-1)*m*2] = a[i-m][j+(t-1)*m*2-m];//右下角等于左上角的值
ﻩﻩa[i][j+(t-1)*m*2-m] =a[i-m][j+(t-1)*m*2];//左下角等于右上角的值
ﻩ}
ﻩ}
ﻩ}
ﻩm*=2;
ﻩ}
}
4-6 放苹果问题完全一致
#include <iostream>
ing namespace std;
2.int c(int ,int);
3.inti=0;
4.void main(){
5.int n,m,count=0;
6. cin>>count;
7.while(count--){
8.cin>>n>>m;
9. cout<<c(n,m)<<endl;
10. }
11.}
12.int c(intn,int m){
13.if(n<=1||m<=1)
14.return 1;
15.if(m>n)
16.returnc(n,n-1);
17.else
18.return c(n,m-1)+c(n-m,m);
}
邮局选址
在一个按照东西和南北方向划分成规整街区的城市里,n个居民点散乱地分布在不同的街区中。
用x坐标表示东西向,用y坐标表示南北向。
各居民点的位置可以由坐标(x,y)表示。
街区中任意2点(x1,y1)和(x2,y2)之间的距离可以用数值|x1-x2|+|y1-y2|度量。
居民们希望在城市中选择建立邮局的最佳位置,使n个居民点到邮局的距离总和最小。
给定n个居民点的位置,编程计算n个居民点到邮局的距离总和的最小值。
#include<stdio.h>
int sum(int a[10001],intn){
int s=0,i;
for(i=0;i<n;i++){
if(a[i]>a[n/2])s+=a[i]-a[n/2];
else s+=a[n/2]-a[i];return s;
}}
voidpaixu(inta[10001],int n){
inti,j,tem;
for(i=0;i<n;i++)
{for(j=i+1;j<n;j++)
if(a[i]>a[j])
{tem=a[i];a[i]=a[j];a[j]=tem;}}}
intmain(){
int i,x,y,n,ax[10001],ay[10001];scanf("%d",&n);for(i=0;i<n;i++)
scanf("%d%d",&ax[i],&ay[i]);paixu(ax,n);paixu(ay,n);
printf("%d\n",sum(ax,n)+sum(ay,n));
4-9煎饼排序
# Sorts Pan
cakes
def sortPancakes(stack):
sorted_index =10
fori inreversed(range(len(stack))):
stack =flip(stack, findLargestPancake(stack, i))
print("Flip Up", stack)
stack =flip(stack,i)
print("Flip Down", stack)
returnstack
# All of the pancakes are sorted after
index
# Returns theindex of largest unsorted
pancake
deffindLargestPancake(stack, index):
largest_pancake =stack[index]
largest_index =index;
fori inrange(index):
if stack[i] >largest_pancake:
largest_pancake=stack[i]
largest_index =i
print""
print("Insert Spatula in index", largest_index, "Siz e",largest_pancake)
return largest_index
defflip(stack,index):
newStack =stack[:(index +1)]
newStack.reverse()
newStack += stack[(index +1):]
returnnewStack
stack = [1, 4, 5, 2, 3, 8, 6, 7, 9, 0]
print"\nUnsorted:"
print stack
print"\nIterating:"
stack = sortPancakes(stack)
print"\nSorted:"
print stack
print""。