实验目的:
理解枚举法的思想及程序的执行过程;
理解递推算法的思想;
能较熟练地编写枚举、递推程序,对给定的问题能设计出相应算法予以解决。
实验环境:
VC6.0
实验内容:
1.由0到4五个数字,组成5位数,每个数字用一次,但十位和百位不能为3(当然万位不能为0),输出所有可能的五位数。
源代码:
#include <iostream>
#include <algorithm>
using namespace std;
int judge(int a[])
{
if(a[0]==0||a[2]==3||a[3]==3)
return
0;
}
int main()
{
int a[5] ={0,1,2,3,4},i;
do{
if(judge(a))
{
for(i=0;i<=4;i++)
cout<<a[i];
cout<<endl;
}
}while(next_permutation(a,a+5));
return 0;
}
截图:
- 最大子段和问题。给定由n个整数组成的序列,求序列中子段的最大和,若所有整数均为负整数时定义最大子段和为0。
例如, 当(a1,a2,a3,a4
,a5,a6) = (-2,11,-4,13,-5,-2)时,最大子段和为:
a2+a3+a4=20
输入格式:
第一行输入整数个数n(1≤n≤10000),再依次输入n个整数。
输出格式:
输出第一行为最大子段和,第二行为子段第一个数和最后一个数在整个序列中的位序。
输入样例1:
6
-2 11 -4 13 -5 -2
输出样例1:
20
2 4
源代码:
#include <iostream>
using namespace std;
int main()
{
int n,i,sum,x,y,flag;
sum=0;
flag=0;
int *a;
cin>>n;
if(n>=1&&n<=10000)
{
a=(int*)malloc(sizeof(int)*n);
for(i=0;i<n;i++)
cin>>a[i];
for(i=0;i<n-2;i++)
{
if(sum<=(a[i]+a[i+1]+a[i+2]))
{
sum=a[i]+a[i+1]+a[i+2];
x=i+1;
y=i+3;
flag++;
}
}
if(flag>0)
{
cout<<sum<<endl;
cout<<x<<" "<<y<<endl;
}
else
cout<<0<<endl;
}
else
cout<<"error"<<endl;
return 0;
}
截图:
3.有两队选手每队5人进行一对一的比赛,甲队为A、B、C、D、E,乙队为J、K、L、M、N,经过抽签决定比赛对手名单。规定A不和J比赛, M不和D及E比赛。列出所有可能的比赛名单。
源代码:
#include <iostream>
using namespace std;
int main()
{
char a[5]={'A','B','C','D','E'},b[5]={'J','K','L','M','N'};
int sum,j,k,l,m,n;
sum=0;
for(j=0;j<5;j++)
{
if(j==0)
continue;
for(k=0;k<5;k++)
{
if(k==j)
continue;
for(l=0;l<5;l++)
{
if(l==j||l==k)
continue;
for(m=0;m<5;m++)
{
if(m==j||m==k||m==l)
continue;
if(m==3)
continue;
for(n=0;n<5;n++)
{
if(n==3)
continue;
if(n==j||n==k||n==l||n==m)
continue;
sum++;
cout<<"第 "<<sum<<" 种比赛名单"<<endl;
cout<<a[0]<<"------"<<b[j]<<endl;
cout<<a[1]<<"------"<<b[k]<<endl;
cout<<a[2]<<"------"<<b[l]<<endl;
cout<<a[3]<<"------"<<b[m]<<endl;
cout<<a[4]<<"------"<<b[n]<<endl;
}
}
}
}
}
cout<<"一共有 "<<sum<<" 种比赛名单"<<endl;
return 0;
}
截图:
4.有5个海盗,相约进行一次帆船比赛。比赛中天气发生突变,他们都被冲散了。恰巧,他们都先后经过途中的一个无名的荒岛,并且每个人都信心满满,觉得自己是第一个经过该岛的人。
第一个人在沙滩上发现了一堆金币。他把金币分成了5等份。发现刚好少一个金币。他就从自己口袋拿出一个金币补充进去,然后把属于自己的那份拿走。
第二个人在沙滩上发现了一堆金币。他也和第一个人一样,把金币分成了5等份。发现刚好缺少一个金币。于是自己补进去一个,然后把属于自己的那份拿走。
第三人,第四人,第五人的情况一模一样。
等他们到了目的地,都说自己的情况,才恍然大悟,一起去荒岛找金币,然而再也没有找到荒岛。他们都惋惜地说:岛上还有一千多枚金币呢!
请推算荒岛上最初有多少个金币?
源代码:
#include <iostream>
using namespace std;
int main()
{
int a[5],k,n;
int i=1;
int flag=0;
for(n=1000;n<=2000;n++)
{
a[4]=n*5/4-1;
for(k=3;k>=0;k--)
{
a[k]=a[k+1]*5/4-1;
if(a[k+1]%4!=0)
{
flag=1;
}
}
if(flag==0)
{
cout<<"第 "<<i<<" 种"<<endl;
cout<<"岛上还剩余的金币数量:"<<n<<endl;
cout<<"荒岛上最初有 "<<a[0]<<" 个金币"<<endl;
cout<<endl;
i++;
}
flag=0;
}
return 0;
}
截图:
5.任意给定一个正整数N,如果是偶数,执行:N/2;如果是奇数,执行:N*3+1。生成的新的数字再执行同样的动作,循环往复。通过观察发现,这个数字会一会儿上升到很高,一会儿又降落下来。就这样起起落落的,但最终必会落到“1”,这有点像小冰雹粒子在冰雹云中翻滚增长的样子。比如N=9:
9,28,14,7,22,11,34,17,52,26,13,40,20,10,5,16,8,4,2,1
可以看到,N=9时,这个“小冰雹”最高冲到了52这个高度。
输入格式:一个正整数N(N<1000000)
输出格式:一个正整数,表示不大于N的数字,经过冰雹数变换过程中,最高冲到了多少。
例如,输入:
10
程序应该输出:
52
再例如,输入:
100
程序应该输出:9232
源代码:
#include <iostream>
using namespace std;
int main()
{
int a,i,b;
cin>>a;
int max=0;
for(i=1;i<a;i++)
{ b=i;
while(b!=1)
{
if(b%2==0)
b=b/2;
else
b=b*3+1;
if(max<b)
max=b;
}
}
cout<<max<<endl;
}
截图:
心得体会
通过本次实验,我理解了枚举法的思想及程序的执行过程,并能较熟练地编写枚举、递推程序,对给定的问题能设计出相应算法予以解决,对于一些递推算法我也能简单得掌握并用代码实现出来。