第十章-训练参考

习题 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;
}
相关推荐
岛雨QA2 小时前
稀疏数组和队列「Java数据结构与算法学习笔记2」
数据结构·算法
沉在嵌入式的鱼2 小时前
温度嵌入式软件算法补偿方案及步骤
stm32·单片机·算法·温度传感器·温度补偿
岛雨QA2 小时前
数据结构和算法概述「Java数据结构与算法学习笔记1」
数据结构·算法
菜鸡儿齐2 小时前
leetcode-有效的括号
linux·算法·leetcode
We་ct2 小时前
LeetCode 102. 二叉树的层序遍历:图文拆解+代码详解
前端·算法·leetcode·typescript
历程里程碑2 小时前
26信号处理一:从闹钟到进程控制的奥秘
linux·运维·服务器·开发语言·c++·算法·排序算法
Gofarlic_OMS2 小时前
LS-DYNA许可证全局状态及集群计算资源使用可视化监控大屏
运维·开发语言·算法·matlab·自动化
载数而行5202 小时前
算法系列4之插入排序
数据结构·c++·算法·排序算法