把 MM 个同样的球放到 NN 个同样的袋子里,允许有的袋子空着不放,问共有多少种不同的放置方法?(用 KK 表示)。
例如, M=7M=7,N=3N=3 时,K=8K=8;在这里认为 (5,1,1)(5,1,1) 和 (1,5,1)(1,5,1) 是同一种放置方法。
问:M=8M=8,N=5N=5 时,K=K=__18__。
使用列举法解决,注意做到不重、不漏。建议按照有球袋子数分类列举,每种方案严格按照非降排列(省略空袋子):
11 个有球的袋子:(8)(8)
22 个有球的袋子:(1, 7)(2, 6)(3, 5)(4, 4)(1,7)(2,6)(3,5)(4,4)
33 个有球的袋子:(1, 1, 6)(1, 2, 5)(1, 3, 4)(2, 2, 4)(2, 3, 3)(1,1,6)(1,2,5)(1,3,4)(2,2,4)(2,3,3)
44 个有球的袋子:(1, 1, 1, 5)(1, 1, 2, 4)(1, 1, 3, 3)(1, 2, 2, 3)(2, 2, 2, 2)(1,1,1,5)(1,1,2,4)(1,1,3,3)(1,2,2,3)(2,2,2,2)
55 个有球的袋子:(1, 1, 1, 1, 4)(1, 1, 1, 2, 3)(1, 1, 2, 2, 2)(1,1,1,1,4)(1,1,1,2,3)(1,1,2,2,2)
故总方案数为 1 + 4 + 5 + 5 + 3 = 181+4+5+5+3=18。
#include <iostream>
using namespace std;
int main()
{
int a, b, c, d, ans;
cin >> a >> b >> c;
d = a - b;
a = d + c;
ans = a * b;
cout << "Ans = " << ans << endl;
return 0;
}
输入:2 3 4
输出:Ans = 9
按照顺序计算即可,注意不要漏掉提示信息“Ans = ”。
d=a-b=2-3=-1d=a−b=2−3=−1
a=d+c=(-1)+4=3a=d+c=(−1)+4=3
ans=a\times b=3\times =9ans=a×b=3×=9
因此正确答案为“Ans = 9”(不含引号,注意不要漏掉提示信息,也不要漏掉空格)。
#include <iostream>
using namespace std;
int fun(int n)
{
if(n == 1)
return 1;
if(n == 2)
return 2;
return fun(n - 2) - fun(n - 1);
}
int main()
{
int n;
cin >> n;
cout << fun(n) << endl;
return 0;
}
输入:7
输出:-11
fun为递归函数,直接模拟难度较大。如果把fun视为数列,参数 nn 视为该序列的项数,则容易发现,该序列满足 fun(1) = 1, fun(2) = 2, n \ge 3fun(1)=1,fun(2)=2,n≥3时,fun(n) = fun(n - 2) - fun(n - 1)fun(n)=fun(n−2)−fun(n−1)。而本题的目标转化为求数列的第 77 项,因此可以使用递推依次计算数列各项:

(数字删除)下面程序的功能是将字符串中的数字字符删除后输出。请填空。
#include <iostream>
using namespace std;
int delnum(char *s)
{
int i, j;
j = 0;
for(i = 0; s[i] != '\0'; i++)
if(s[i] < '0' ① s[i] > '9')
{
s[j] = s[i];
②;
}
return ③;
}
const int SIZE = 30;
int main()
{
char s[SIZE];
int len, i;
cin.getline(s, sizeof(s));
len = delnum(s);
for(i = 0; i < len; i++)
cout << ④;
cout << endl;
return 0;
}
填空位置 ①:
||
填空位置 ②:
j++
填空位置 ③:
j
填空位置 ④:
s[i]
此题考查简单的字符串处理。delnum就是删数字函数,len是删完的长度,逐个访问字符 s[i],如果不是数字字符,就是有效字符,保存至s[j],j是用来记非数字的最后一位。
①空中需要判断当前字符是不是数字,字符为不为数字的条件此处应该为或关系。
②空中需要将i位置上的字符赋值给j位置。这之后需要更新非数字的最后一位的位置,因此需要将j加一。
③空中需要范围处理后的字符串的长度,因此我们需要返回j。
④空我们需要输出最后的结果因此我们需要输出s[i]。
(最大子矩阵和)给出 mm 行 nn 列的整数矩阵,求最大的子矩阵和(子矩阵不能为空)。
输入第一行包含两个整数 mm 和 nn,即矩阵的行数和列数。之后 mm 行,每行 nn 个整数,描述整个矩阵。程序最终输出最大的子矩阵和。
#include <iostream>
using namespace std;
const int SIZE = 100;
int matrix[SIZE + 1][SIZE + 1];
int rowsum[SIZE + 1][SIZE + 1]; //rowsum[i][j]记录第 i 行前 j 个数的和
int m, n, i, j, first, last, area, ans;
int main()
{
cin >> m >> n;
for(i = 1; i <= m; i++)
for(j = 1; j <= n; j++)
cin >> matrix[i][j];
ans = matrix ①;
for(i = 1; i <= m; i++)
②
for(i = 1; i <= m; i++)
for(j = 1; j <= n; j++)
rowsum[i][j] = ③;
for(first = 1; first <= n; first++)
for(last = first; last <= n; last++)
{
④;
for(i = 1; i <= m; i++)
{
area += ⑤;
if(area > ans)
ans = area;
if(area < 0)
area = 0;
}
}
cout << ans << endl;
return 0;
}
填空位置 ①:
[1][1]
填空位置 ②:
rowsum[i][0]=0;
填空位置 ③:
rowsum[i][j-1]+matrix[i][j]
填空位置 ④:
area=0
填空位置 ⑤:
rowsum[i][last]-rowsum[i][first-1]
本题解决最大子矩阵和所用的算法:计算数组rowsum;枚举子矩阵的左边界first和右边界last,将原问题转化为求解一维的最大子段和问题,用贪心法即可解决。
①因为所求最大子矩阵和所涉及的子矩阵不能为空,必须有一个初值,所以我们需要将ans设置为矩阵的左上角元素,也就是 [1][1][1][1],取其他单元格的值也可以;
②因为后面要求每行前缀和,所以需要将 00 列清零,用于之后的统计;
③求当前行到当前列的前缀和,使用前缀和的方法统计每行的sum值;
④从first列到last列之间求最大子段和,需要将当前的值初始化为 00;
⑤这里求第i行的first列到last列之间的数值和,这里采用前缀和方法来加速计算过程。
这篇博客介绍了如何解决将一定数量的球放入相同袋子的问题,通过列举不同放置方式来求解。文章通过具体例子展示了如何按照有球袋子数进行分类列举,并给出了C++代码实现。同时,还涉及到递归函数的应用和最大子矩阵和的计算方法,包括相关代码示例。
710

被折叠的 条评论
为什么被折叠?



