NOIP2014普及组初赛难点整理
程序员文章站
2022-04-21 10:23:08
问题求解把 MMM 个同样的球放到 NNN 个同样的袋子里,允许有的袋子空着不放,问共有多少种不同的放置方法?(用 KKK 表示)。例如, M=7M=7M=7,N=3N=3N=3 时,K=8K=8K=8;在这里认为 (5,1,1)(5,1,1)(5,1,1) 和 (1,5,1)(1,5,1)(1,5,1) 是同一种放置方法。问:M=8M=8M=8,N=5N=5N=5 时,K=K=K=____。【解析】nnn个相同的球放入mmm个相同的盒子(n≥mn≥mn≥m),可以有空盒时的放法种数等于将nnn分解...
问题求解
- 把 个同样的球放到 个同样的袋子里,允许有的袋子空着不放,问共有多少种不同的放置方法?(用 表示)。例如, , 时,;在这里认为 和 是同一种放置方法。
问:, 时,____。
【解析】个相同的球放入个相同的盒子(),可以有空盒时的放法种数等于将分解为个、个、个、…、个、个数的和的所有种数之和。
将8
分解为个数:8
,共种
将8
分解为个数:1+7
,2+6
,3+5
,4+5
,共种
将8
分解为个数:1+1+6
,1+2+5
,1+3+4
,2+2+4
,2+3+3
,共种
将8
分解为个数:1+1+1+5
,1+1+2+4
,1+1+3+3
,1+2+2+3
,2+2+2+2
,共种
将8
分解为个数:1+1+1+1+4
,1+1+1+2+3
,1+1+2+2+2
,共种
答案:18
- 如图所示,图中每条边上的数字表示该边的长度,则从 到 的最短距离是____。
【解析】正权图的最短路,可以使用Dijkstra算法求解。
阅读程序写结果
#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
【解析】模拟递归调用的结果如下:
f(1) | f(2) | f(3) | f(4) | f(5) | f(6) | f(7) |
---|---|---|---|---|---|---|
1 | 2 | -1 | 3 | -4 | 7 | -11 |
输出:-11
2.
#include <iostream>
using namespace std;
const int SIZE = 100;
int main()
{
int p[SIZE];
int n, tot, i, cn;
tot = 0;
cin >> n;
for(i = 1; i <= n; i++)
p[i] = 1;
for(i = 2; i <= n; i++)
{
if(p[i] == 1)
tot++;
cn = i * 2;
while(cn <= n)
{
p[cn] = 0;
cn += i;
}
}
cout << tot << endl;
return 0;
}
输入:30
输出:10
【解析】埃氏筛素数法。
对正实数,定义为不大于的素数个数, , 其中,为的自然对数, ,。
完善程序
(最大子矩阵和)给出 行 列的整数矩阵,求最大的子矩阵和(子矩阵不能为空)。
输入第一行包含两个整数 和 ,即矩阵的行数和列数。之后 行,每行 个整数,描述整个矩阵。程序最终输出最大的子矩阵和。
#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;
}
【解析】利用前缀和的思想,计算出矩阵第i
行前j
列的和rowsum[i][j]
。枚举所有列的组合,求出子矩阵和的最大值。
- 空①,初始化ans
,让其等于矩阵第一行第一列的值matrix[1][1]
,所以应填入[1][1]
- 空②,初始化每行前缀和数组的第0
项,将其置为,用于之后计算前缀和,所以应填入rowsum[i][0]=0
- 空③,计算第i
行的前缀和,所以应填入rowsum[i-1]+matrix[i][j]
- 空④,初始化area
为,所以应填入area=0
- 空⑤,使用前缀和数组计算first
列到last
列的和,rowsum[i][last]-rowsum[i][first-1]
。
本文地址:https://blog.csdn.net/qiaoxinwei/article/details/107889469