2.4-课堂练习

1、输入一串以‘!’结束的字符,按逆序输出。(用递归做)

#include <cstdio>
void sort()
{
	char ch;
	if((ch=getchar())!='!')  
	{
		sort() ; 
		putchar(ch);
	}
	return;
}
int main()
{
	sort();
}

2、背包问题
  问题:假设有n件质量分配为w1,w2,…,wn的物品和一个最多能装载总质量为T的背包,能否从这n件物品中选择若干件物品装入背包,使得被选物品的总质量恰好等于背包所能装载的最大质量,即wi1+wi2+…+wik=T。若能,则背包问题有解,否则无解。
(例如:有5件可选物品,质量分别为8千克、4千克、3千克、5千克、1千克。假设背包的最大转载质量是10千克。)

#include<iostream>
using namespace std;
int k(int s,int n,int a[])
{
	if(s==0)
	{
		return (1);
	}
	else
	{
		if(s<0||(s>0&&n<1))
		{
			return (0);
		}
		else
		{
			if(k(s-a[n-1],n-1,a))
				{
					cout<<"number:"<<n<<"  "<<"weight:"<<a[n-1]<<endl;
					return (1);
				}
			else
			{
				return k(s,n-1,a);
			}
		}
	}
		
}
int main()
{
	int S,n,a[100],t;
	cin>>n>>S;
	for(int i=0;i<n;i++)
		cin>>a[i];
		t=k(S,n,a);
		if(t==0)
		cout<<"not found"<<endl;
}

3、阿克曼(Ackmann)函数A(x,y)中,x,y定义域是非负整数,函数值定义为:
akm(m,n) = n+1; (m=0时)

akm(m,n) = akm(m-1,1); (m>0,n=0时)

akm(m,n) = akm(m-1,akm(m, n-1)); (m,n>0时)
写出计算Ack(m,n)的递归算法程序。

#include <iostream>
#include<cstdio>
using namespace std;

int akm(int m,int n){
    if(m==0) return n+1;
    if(m>0&&n==0)return akm(m-1,1);
    return akm(m-1,akm(m, n-1));
}
int main(){
    
    int m,n;
    cin>>m>>n;
    cout<<akm(m,n);
    
}

4、某人写了n封信和n个信封,如果所有的信都装错了信封。求所有的信都装错信封共有多少种不同情况。
基本形式:d[1]=0;d[2]=1
递归式:d[n]= (n-1)*( d[n-1] + d[n-2])

#include <iostream>
#include<cstdio>
using namespace std;

int ak(int n){
    int d[101];
    d[1]=0;
    d[2]=1;
    for(int i=3;i<=n;i++)
    {
    	d[i]=(i-1)*(d[i-1]+d[i-2]);
	}
	return d[n];
}
int main(){
    
    int n;
    cin>>n;
    cout<<ak(n);
    
}

5、有52张牌,使它们全部正面朝上,从第2张开始,凡是2的倍数位置上的牌翻成正面朝下;接着从第3张牌开始,凡是3的倍数位置上的牌,正面朝上的翻成正面朝下,正面朝下的翻成正面朝上;接着第三轮从第4张牌开始,凡是4的倍数位置上的牌按上面相同规则翻转,以此类推,直到第1张要翻的牌是第52张为止。统计最后有几张牌正面朝上,以及它们的位置号。

 #include<iostream>
 using namespace std;
 int a[1001];// 0正面朝上 
 void f(int n)
 {
    if(n==53)
    return;
    else
    {
      for(int i=1;i<=52;i++)
      {
         if(i%n==0)
         {
            if(a[i]==0)
            a[i]=1;
		 else a[i]=0;
		} 
     } 
     f(n+1);
  }
}
int main()
{
   f(2);
   int tot=0;
   for(int i=1;i<=52;i++)
   {
       if(a[i]==0)
       {
           tot++;
           cout<<i<<" ";
       }
  }
  cout<<endl;
  cout<<tot;
  return 0;
}

6、猴子吃桃问题
猴子第一天摘下若干桃子,当即吃了一半,还不过瘾,又多吃了一个。第二天早上又将剩下的桃子吃掉的一半,又多吃了一个。以后每天早上都吃掉了前一天剩下的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。求第一天共摘多少桃子。(答案:1534)

#include <cstdio>
int main()
{
	int i,n=1;
	for(i=9;i>=1;i--)
	{
		n=(n+1)*2;
	}
	printf("第1次共摘了%d个桃子\n",n);
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值