3.3、算法练习
一、自由练习
阶乘计算
1)资源限制
时间限制:1.0s 内存限制:512.0MB
2)问题描述
输入一个正整数n,输出n!的值。
其中n!=12 * 3 … n。
3)算法描述
n*!可能很大,而计算机能表示的整数范围有限,需要使用高精度计算的方法。使用一个数组A来表示一个大整数a,A[0]表示a的个位,A[1]表示a的十位,依次类推。
将a乘以一个整数k变为将数组A的每一个元素都乘以k,请注意处理相应的进位。
首先将a设为1,然后乘2,乘3,当乘到n时,即得到了n!的值。
4)输入格式
输入包含一个正整数n,n<=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;
}