当前位置:文档之家› 算法设计第四章部分作业

算法设计第四章部分作业

算法:
输入:火柴的数量和第二个让人拿的火柴数量
输出:第一个拿的火柴数量
1.构造fun()函数,让A拿的火柴数是第二个人拿完后的数量模5的值
2.判断n%5的值
3.如果模值不等于0,调用fun()函数
4.进行递归调用fun知道火柴拿完为止
程序:
//火柴问题,如果火柴根数是5的倍数,那么只要B不是傻瓜A就输定了!反之如果不是5的倍数,那么A每次只要拿n%5的模值就一定能赢
r[m]=r[n-1];
r[n-1]=temp;
}
HeapSort(r, n-1);
for( i=0;i<7;i++)
cout<<r[i]<<" ";
return 0;
}
void SiftHeap(int r[ ], int k, int n)
{
int i, j, temp;
i = k; j = 2 * i +1; //置i为要筛的结点,j为i的左孩子
cout<<r[i]<<" ";
cout<<endl;
cout<<"大根堆中要删除的元素的下标为:";
cin>>m;//输入大根堆中要删除的元素的下标
if(m<0||m>=n)
cout<<"要删除的元素的不存在"<<endl;
else
{
int temp;
temp=r[m];//将该元素的下标与大根堆最后一个元素交换,然后将前n-1个元素进行大根堆排序即可
{
if(i<=(m+k)/2)
{
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
void xun(char a[],int k,int n)//(函数2)第二个调用函数,调用函数1
{
fun(a,0,k-1);//第一次调用函数1,将(abc)对称交换得到(cba),最后a[]为(cbadefgh)
b=b*2;
}
}
count=a*b+s;
return count;
}
int main()
{
int m,n;
int sum;
cout<<"请输入两个乘数:";
cin>>n>>m;
sum=fun(n,m);
cout<<"计算结果为:";
cout<<sum<<endl;
return 0;
}
第8题:
想法:
对于火柴游戏,如果起初所有火柴的数量是5的倍数,那么第一个人是不能赢的,如果要第一个人赢得游戏,那么,要在火柴数量不是5的倍数的情况下进行,不管第二个人拿几根火柴,只要第一个人拿的数量是n%5的模值即可赢得游戏!
else fun(n);
return 0;
}
第10题:
想法:
这个想法是基于已知假币的轻重的情况下进行的,我假设假币比真币轻来进行试验,也可以假设假币比真币重,只需要稍微改写一下程序即可。首先,我将硬币分成3堆,用数组来存放硬币的重量,随便假设一个数组元素为假,用累加判断大小的方式来判断假币出现在哪一堆分组中,对可能出现的三种情况进行递归调用Coin()函数来进行循环判断,直到找到假币为止
cout<<a<<"和"<<b<<"的最大公倍数是:"<<s<<endl;
return 0;
}
int CommFactor2(int m, int n)//返回两个数的最大公约数
{
int r = m % n;
while (r != 0)
{
m = n;
n = r;
r = m % n;
}
return n;
算法:
1.输入:一个数组和左移位数
2.编写两个函数,一个是对称交换函数1,另一个是调用函数2,用函数2三次调用函数1,完成整个对称交换过程。
3.调用函数2
4.输出:左移后的数组
程序:
/*(升级版2)这个是用分治法将一个字符串(abcdefgh)左移3位(defghabc),具体用到的方法是对称交换和调用函数*/
3.建立初始大根堆
4.输入要删除的元素的下标
5.将要删除的元素与最后一个一个元素交换
6.建立前n-1个元素的大根堆
程序:
//想法:先将已知序列排列成一个大根堆,删除某个元素后,将最后一个元素赋值给删除节点,然后再进行堆排序(堆排序只是有序排序中的一部分)
#include <iostream.h>
void HeapSort(int r[ ], int n);//建立堆以及堆中元素整体排序
const int N = 12; //假设求解12枚硬币问题
int a[N] = {2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2};
int Coin(int low, int high, int n);
int main()
{
int i=Coin(0,11,12);
cout<<"假币是第"<<i<<"个"<<endl;
return 0;
}//真币的重量是2,假币的重量是1
int Coin(int low, int high, int n) //在a[low]~a[high]中查找假币
{
int i, num1, num2, num3; // num1、num2和num3存储3组硬币的个数
int add1 = 0, add2 = 0; //add1和add2存储前两组硬币的重量和
算法:
输入:一个数组用来存放硬币的重量
输出:假币的位置
1.构造Coin()函数,将硬币分成三堆,如果硬币数量是3的倍数则均分成3组,如果不是则前两组分成n/3+1
2.累加比较重量来判断假币出现的地方
3.递归循环调用Coin()函数
4.返回假币的下标
5.在主函数中调用Coin()函数,输出结果
程序:
#include <iostream.h>
i = j; j = 2 * i+1; //被筛结点位于原来结点j的位置
}
}
}
void HeapSort(int r[ ], int n)
{
int i;
for (i = (n-1)/2; i >= 0; i--) //初始建堆,从最后一个分支结点至根结点
SiftHeap(r, i, n) ;
}
第7题:
算法第4-7章部分答案
第四章
第4题:
想法:
求两个正整数m和n的最小公倍数,由题目给出的提示可以知道,m和n的最小公倍数等于两个数的积除以它们的最大公约数。在第一张的事后要我们就已经用欧几里德算法求过两个数的最大公约数,所以对于题目4,我们就可以直接引用欧几里德算法辅助求最小公倍数。
算法:
输入:两个自然数m和n
else //在第3组查找,下标范围low+num1+num2~high
Coin(low + num1 + num2, high, num3);
}
第五章
第6题:
想法:
对于第6题,用分治法进行求解的话,若是采用循环赋值的方式,如果字符的个数和左移的位数成倍数关系,那么算法就比较容易实现,但是如果不成比例关系,算法写起来就比较麻烦,所以,我用了另一种方式,进行三次对称交换就可以完成算法。
if (n == 1) //递归结束的条件
return low + 1; //返回的是序号,即下标加1
if (n % 3 == 0) //3组硬币的个数相同
num1 = num2 = n / 3;
else
num1 = num2 = n / 3 + 1; //前两组有n / 3 + 1枚硬币
num3 = n - num1 - num2;
想法:
求两个数的乘积,根据已知提示可以采用俄式乘法,即是采用减治法将被乘数一直减小到1,同时将乘数以2倍的方式增大,同时将减去过程中产生的数累加最后一个求和
算法:
输入:两个正整数
输出:l两个数的乘积
1.构造一个俄式乘法函数fun()
2.输入两个数,对两个数比较大小,将较小的数作为被乘数
3.判断被乘数的奇偶性,若是偶数则减半,若是技术则减1再减半
cout<<"出错了!您只能拿1—4根火柴:"<<endl;
else
{
n=n-j;
return fun(n);//递归调用函数
}
}
}
}
int main()
{
cout<<"请输入火柴根数:";
int n;
cin>>n;
if(n%5==0)
cout<<"放弃吧!在B不是傻瓜的情况下A输定了!"<<endl;
4.进行while循环做递归处理
5.返回最后的值
6.调用函数输出结果
程序:
//俄式乘法算法
#include<iostream>
using namespace std;
int fun(int a,int b)
相关主题