第十章-训练参考

习题 10-1 砌砖 Add bricks in the wall

题目描述了一个有9层的砖墙金字塔。规则很简单:每个砖块上的数字,等于它下方支撑的两个砖块数字之和。题目只给出了所有奇数行中,奇数位置上的数字(比如第1行第1个,第3行第1个、第3个......),要求我们求出墙上所有砖块的数字,并且保证有唯一解。

思路

由于每一块砖上被标识的整数是其下面两块砖上的整数之和,所以,对于三角形墙中的任何一个三角形:

第一行:c

第二行:a+x,x+b

第三行:a,x,b

其中,位于奇数行奇数位置的 a,b,c 已知,则有 c=(a+x)+(b+x),则 x=2c−a−b​。

由此可知:

  • 首先计算位于奇数行偶数位置的元素值 x。

  • 然后计算出位于偶数行的元素值。

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
int a[9][9];

int main() {
	int t;
	cin >> t;
	while (t--) {
		for (int i = 0; i < 9; i++) {
			for (int j = 0; j <= i; j += 2) {
				cin >> a[i][j];
			}
		}
		for (int i = 8; i > 0; i-= 2) {
			for (int j = 1; j < i; j += 2) {
				a[i][j] = (a[i - 2][j - 1] - a[i][j - 1] - a[i][j + 1]) / 2;
			} 
		}
		for (int i = 1; i < 9; i += 2) {
			for (int j = 0; j <= i; j++) {
				a[i][j] = a[i + 1][j] + a[i + 1][j + 1];
			}
		}
		for (int i = 0; i < 9; i++) {
			for (int j = 0; j <= i; j++) {
				cout << a[i][j] << " ";
			}
			cout << "\n";
		}
	}
	return 0;
}

习题 10-9 约数 Divisors

给定 n 个区间 l,r,求出每个区间内约数个数最大的数。

数据范围:1⩽l<r⩽1010,r−l⩽104。

需要了解 约数个数定理

解法

习题 10-17 H-半素数 Semi-prime H-numbers

给你一个由 4n+1 的数组成的集合,该集合中的数被称为 H 数,集合中的素数是 H− 素数, 两个 H− 素数的乘积组成的数被称为H− 合成数,现在给定一些 h ,求 0,h 中的 H− 合成数的个数。

解:我这个看了好久才看题解弄明白,这里我就直接放我认为详细清晰的了。

习题 10-22 飞机环球 Planes around the World

这道题没翻译,我用AI简化翻译的:

  • 问题背景 :飞机从A点出发,油箱满油可飞 a/b 圈(即全球周长的 a/b)。飞机之间可在瞬间互相加油(但不能超过油箱容量)。目标是让至少一架飞机成功环球飞行(飞完1圈)并返回起点,同时所有参与飞机最终都能安全返回A点。

  • 输入与输出 :输入多组 ab,输出达到目标所需的最少飞机总数。如果无解(需求超过一万架),则输出 -1

  • 关键限制条件 :题目为了简化,给出了特定的调度规则(你提供的图2是 a=1, b=2 时需要5架的经典案例),这直接引导了我们的解题方向。

解:

首先考虑正向飞行的飞机,我们仿照样例中的走法,考虑n架飞机正向飞行的情况(包括一号飞机),题目中要求一架飞机需要给其它飞机加相同的油,所以我们每次都让一架飞机把其它飞机的油加满,然后该飞机返回起点。为了便于考虑,我们设飞机初始携带的油量为 a/b ​,在上面的要求下,我们发现每次正向飞行的飞机都可以前行 a/b​ × 1/(n+1)​ ,总共有n架飞机,前n−1次飞行,都会前进相同的距离,即 a/b​ × 1/(n+1)​​ ,同时每次少一架飞机返回起点,直至剩余一架飞机,前进 a/b ,所以正向行驶 a/b​ × (n-1)/(n+1)​ + a/b​ ,显然,我们发现,如果 a/b​ 小于等于 1/3​ ,是无法完成旅行的,因为反向飞行的飞机无法接应。

对于反向的飞机,采用相似的想法,但是注意此时应该保证每架飞机的油量相同,以便可以一起飞到下一个反向飞机处接应。

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

int cal(int a,int b)
{
    if(b >= 3*a) return -1;
    int Min = 10000;
    double dis = 0.0,A=a,B=b;
    for(int i=1;i <= Min; i++){
        dis = 0.0;
        dis = dis + double(i-1)/double(i+1) * (A/B) + A/B;
        int m=1;
        while(dis < (1-(1e-6)))
        {
            dis = dis + ((A/B) - (1 - dis)) / (m+1);
            if(m+i>Min) break;
            m++;
        }
        Min = min(m+i-1,Min);
    }
    return Min;
}

int main()
{
    int a,b,T,cnt=1;
    cin >> T;
    while(T--){
        cin >> a >> b;
        cout <<"Case " << cnt <<": " <<cal(a,b) << endl;
        cnt++;
    }
    return 0;
}
相关推荐
JieE21215 小时前
LeetCode 56. 合并区间|超清晰 JS 图解思路,面试高频区间题
javascript·算法·面试
Jack201 天前
HarmonyOS开发中错误处理策略:网络异常统一处理
算法
小小杨树1 天前
读懂色彩:拍照调色不再难
算法·计算机视觉·配色
JieE2122 天前
LeetCode 226. 翻转二叉树|JS 递归超详细拆解,二叉树入门经典题
javascript·算法
JieE2122 天前
LeetCode 104. 二叉树的最大深度|递归思路超详细拆解
javascript·算法
vivo互联网技术2 天前
CVPR 2026 | 全新强化学习框架 BeautyGRPO:重塑真实人像
算法·大模型·cvpr·影像
Darling噜啦啦2 天前
列表转树算法深度解析:从 Map 到 Reduce 的两种实现,面试高频考点
数据结构·算法·面试
用户497863050732 天前
(一)小红的数组操作
算法·编程语言
怕浪猫2 天前
Electron 系列文章封面图
算法·架构·前端框架