洛谷——P1012 拼数

原题链接

这个题目的关键在于如何排序,使得其组合后的数最大。

这里我简单证明一下为什么代码中这样排序是正确的,当然这种证明是不严格的,不过毕竟算法题他不考证明不是。

首先,我们要找到一个数q,这个q对任意的w都使得q放在w左侧时都不小于q放在w右侧。那么是否存在这么一个q呢?答案是肯定的。

我们先对只含两个元素的集合{a,b}进行分析。如果ab>=ba(连在一起写表示组合,不是乘积),我们继续考虑第三个元素加入{a,b,c}。如果ac>=ca,显然应该把a排在前面,之后再比较c和b即可。那么这种情况下是符合题设,也就是存在这样的q。

但如果ac<=ca,那么现在的问题是cb是否大于等于bc。不妨假定cb<=bc,那么组合的数应该是bca最大。但是ab>=ba,所以acb>=bca。这样就出现了矛盾,所以假设不成立,也就是cb>=bc。

关键点:由于ca>=ac,ab>=ba,得到了cb>=bc,也就是说这个不等式满足传递性

既然得到了传递性,那么一定就会存在这样一个q。否则大小关系比较不就成一个圈了

这里一直带着等号来写,是因为考虑两个数字完全相同的情况,或是123123和123这种数。如果不太理解可以把所有的等号全部去掉。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
string a[203];
bool cmp(string q, string w) {
	return q + w > w + q;
}

int main()
{
	ios_base::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	int n;
	cin >> n;
	for (int i = 0; i < n; i++) 
		cin >> a[i];
	sort(a, a + n, cmp);
	for (int i = 0; i < n; i++)
		cout << a[i];
	return 0;
}

感觉有帮助的小伙伴点个赞哦~

### 洛谷 P1284 三角形牧场 题目描述 奶牛们希望设计一种新的牧场形状——由漂亮的白色栅栏围成的三角形牧场。建筑师 Hei 手中有 $n$ 块木板,每块木板的长度为整值 $l_i$。她的目标是利用这些木板接出一个能够形成合法三角形的最大面积牧场。 #### 输入格式 输入的第一行为一个正整 $n$ ($3 \leq n \leq 15$),代表拥有的木板量;第二行为 $n$ 个正整 $l_1, l_2, ..., l_n$ ($1 \leq l_i \leq 10^6$),分别表示各木板的长度。 #### 输出格式 如果无法构成任何三角形,则输出 `-1`;否则输出能组成的最大面积,保留两位小。 --- ### 解法分析 此问题的核心在于如何通过给定的木板组合找到满足三角形条件的最佳方案并计算其面积。以下是两种主要方法: #### 方法一:动态规划 (DP) 定义状态 `dp[i][j]` 表示前 $i$ 条边中是否存在两条边分别为 $j$ 和 $c-j-k$ 的情况,其中 $c=\sum_{k=1}^{n}{l_k}$ 是总周长的一半[^2]。转移方程如下: ```cpp if ((j - l[i] >= 0 && dp[j - l[i]][k]) || (k - l[i] >= 0 && dp[j][k - l[i]])) dp[j][k] = true; ``` 最终判断是否能找到三个符合条件的边 $(a,b,c)$ 并验证它们是否可构成三角形: ```cpp inline bool check(int a, int b, int c) { if (a + b > c && a + c > b && b + c > a) return true; return false; } check(i, j, c - i - j); ``` 一旦确认存在这样的三边组合,即可应用 **海伦公式** 计算面积: $$ S = \sqrt{p(p-a)(p-b)(p-c)} $$ 其中 $ p = \frac{a+b+c}{2} $ 是半周长。 --- #### 方法二:搜索算法 另一种解法基于暴力搜索的思想,但由于直接穷举所有可能性会导致超时(TLE),因此需引入剪枝策略优化效率[^4]。具体实现步骤包括但不限于以下几个方面: - 对原始组按升序排列; - 枚举当前尝试加入哪条边上; - 使用回溯技术逐步试探直至完成分配过程; - 结合均值不等式的理论依据进一步缩小候选范围,即倾向于让三条边尽可能接近从而提升潜在最优解的概率。 下面是简化版伪代码展示这一逻辑框架: ```python def dfs(index, sideA, sideB, sideC): global maxArea # 边界处理与更新最佳结果记录 currentPerimeter = sideA + sideB + sideC semiPerimeter = currentPerimeter / 2 areaCandidate = sqrt(semiPerimeter*(semiPerimeter-sideA)*(semiPerimeter-sideB)*(semiPerimeter-sideC)) if isValid(sideA, sideB, sideC): if areaCandidate > maxArea: maxArea = areaCandidate # 继续探索剩余选项 for nextIndex in range(index+1, lengthOfPlanks): newLength = lengths[nextIndex] # 分配至不同边缘之一 dfs(nextIndex, sideA + newLength, sideB , sideC ) dfs(nextIndex, sideA , sideB + newLength, sideC ) dfs(nextIndex, sideA , sideB , sideC + newLength ) # 初始化调用入口函 maxArea = -1 dfs(-1, 0, 0, 0) print("%.2f"%maxArea if maxArea != -1 else "-1") ``` 注意此处仅提供概念示意而非完整可用程序片段。 --- ### 海伦公式的实际运用实例 假设已知某组据样本 $\{7, 9, 12\}$ 可成功构建有效三角形,则对应操作流程如下所示: 设 $s=(7+9+12)/2=14$ 代入得 $$ A=\sqrt{s(s−a)(s−b)(s−c)}=\sqrt{14(14−7)(14−9)(14−12)}≈26.83 $$ ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值