3.3、算法练习

3.3、算法练习

一、自由练习

阶乘计算

1)资源限制

时间限制:1.0s 内存限制:512.0MB

2)问题描述

输入一个正整数n,输出n!的值。
  其中n!=12 * 3 … n。

3)算法描述

n*!可能很大,而计算机能表示的整数范围有限,需要使用高精度计算的方法。使用一个数组A来表示一个大整数aA[0]表示a的个位,A[1]表示a的十位,依次类推。
  将a乘以一个整数k变为将数组A的每一个元素都乘以k,请注意处理相应的进位。
  首先将a设为1,然后乘2,乘3,当乘到n时,即得到了n!的值。

4)输入格式

输入包含一个正整数nn<=1000。

5)输出格式

输出n!的准确值。

6)样例输入

10

7)样例输出

3628800

8)解题思路

在此题中,只用s=s*i不行的。n!可能很大,而计算机能表示的整数范围有限,需要使用高精度计算的方法。

所以我们采用数组来计算

#include<iostream>
using namespace std;
void fun(int n)
{
    int a[100000],tail=0,head=0,p=0;
    if(n==1)
    cout<<"1";
    else
    {
        a[0]=1;
        for(int i=2;i<=n;i++){
        	for(int j=head;j<=tail;j++){
        		p=p+a[j]*i;
                a[j]=p%10;
                p=p/10;
            }
            while(p!=0)
            {
                tail++;
                a[tail]=p%10;
                p=p/10;
            }
        }
        for(int i=tail;i>=0;i--)
            cout<<a[i];
    }
}
int main()
{
    int n;
    cin>>n;
    fun(n);
    return 0;
}

二、视频学习

1)视频链接

https://www.bilibili.com/video/BV1jE411g76D?p=19

2)广度优先搜索

长度优先搜索,又名宽度优先搜索,所遵循的搜索策略是尽可能“广”的遍历搜索树,对应树的分层遍历。在宽度优先搜索中,每次都先将搜索树某一层的所有结点全部访问完毕后再访问下一层,首次达到的目标节点通常就是最优解。

名称广度优先搜索
优点1. 容易解决“最少步数”、“深度最小”问题2. 问题的解靠近解答树的根结点3. 启发式搜索在BFS中更容易实现
缺点1. 空间一般比DFS大2. 状态重复的排除有时耗时多

3)题目描述

农民 John 以拥有世界上最健康的奶牛为傲。他知道每种饲料中所包含的牛所需的最低的维他命量是多少。请你帮助农夫喂养他的牛,以保持它们的健康,使喂给牛的饲料的种数最少。

给出牛所需的最低的维他命量,输出喂给牛需要哪些种类的饲料,且所需的饲料剂量最少。

维他命量以整数表示,每种饲料最多只能对牛使用一次,数据保证存在解。

4)输入格式

第一行一个整数 v,表示需要的维他命的种类数。
第二行 v 个整数,表示牛每天需要的每种维他命的最小量。

第三行一个整数 g,表示可用来喂牛的饲料的种数。
下面 g行,第 n 行表示编号为 n 饲料包含的各种维他命的量的多少。

5)输出格式

输出文件只有一行,包括牛必需的最小的饲料种数 pp;后面有 pp 个数,表示所选择的饲料编号(按从小到大排列)。

如果有多个解,输出饲料序号最小的(即字典序最小)。

6)输入输出样例

输入 #1

4
100 200 300 400
3
50 50 50 50
200 300 200 300
900 150 389 399

输出 #1

2 1 3

7)说明/提示

【数据范围】
对于 100%100% 的数据,1≤v≤25,1≤g≤15。
输入的所有整数在 [1,1000] 范围内。

8)代码实现

#include<iostream>
using namespace std;
 
int ans[100];//存储解 
int a[100];//牛每天需要的每种维他命的最小量。 
int b[100][100];//每种饲料包含的各种维他命的量的多少。
int c[100];//每次搜索选的饲料编号 
int v,g,minn=100000000;

bool pd(int x)//判断 
{
	for(int i=1; i<=v; i++)
	{
		int sum=0;
		for(int j=1; j<=x; j++)
		sum+=b[c[j]][i];
		if(sum<a[i]) return false;//若有一项维生素比所需维生素要少,返回false 
	}
	return true;
}
void search(int t,int s)
{
	if(t>g)//边界
	{
		if(pd(s))
		{
			if(s<minn)//判断选的饲料的总数小于以前的最优解
			{
				minn=s;
				for(int i=1; i<=minn; i++)
				{
					ans[i]=c[i];
				}
			}
		}
		return; 
	}
	c[s+1]=t;//把t放在数组里
	search(t+1,s+1);//搜索一步
	c[s+1]=0;//回溯一步
	search(t+1,s);//如果不选第t种饲料的操作
}
int main()
{
	cin>>v;
	for(int i=1;i<=v;i++){
		cin>>a[i];
	}
	
	cin>>g;
	for(int i=1;i<=g;i++){
		for(int j=1;j<=v;j++){
			cin>>b[i][j];
		}
		
	}
	search(1,0);
	cout<<minn<<' ';
	for(int i=1; i<=minn; i++){
		cout<<ans[i]<<' ';
	}

	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值