C - Hot Bath CodeForces - 127C——贪心

本文介绍了一种通过调节冷热水流量来快速达到目标温度的热水浴控制算法。该算法使用贪心策略,通过不断调整冷热水的最大释放速度,确保混合后的水温最接近指定温度t0,同时尽量加快注水速度。

Think:
1>题意:已知冷水温度t1,热水温度t2,冷水最高释放速度x1,热水最高释放速度x2,问如何控制释放速度可使最快达到正趋向于温水温度t0
1>题意建模:两个水杯温度分别为t1, t2, 体积分别为x1, x2,要得到温度正趋向于温度t0(t0介于t1和t2之间)的最大体积
2>贪心:从最大冷水体积x1开始试探,让最大热水体积x2递减,若混合温度低于t0,则x1-1,最后保留的试探解即为最优解

C - Hot Bath CodeForces - 127C

Bob is about to take a hot bath.

There are two taps to fill the bath: a hot water tap and a cold water tap. The cold water's temperature is t1, and the hot water's temperature is t2. The cold water tap can transmit any integer number of water units per second from 0 to x1, inclusive. Similarly, the hot water tap can transmit from 0 to x2 water units per second.

If y1 water units per second flow through the first tap and y2 water units per second flow through the second tap, then the resulting bath water temperature will be:

这里写图片描述

Bob wants to open both taps so that the bath water temperature was not less than t0. However, the temperature should be as close as possible to this value. If there are several optimal variants, Bob chooses the one that lets fill the bath in the quickest way possible.

Determine how much each tap should be opened so that Bob was pleased with the result in the end.

Input

You are given five integers t1, t2, x1, x2 and t0 (1 ≤ t1 ≤ t0 ≤ t2 ≤ 106, 1 ≤ x1, x2 ≤ 106).

Output

Print two space-separated integers y1 and y2 (0 ≤ y1 ≤ x1, 0 ≤ y2 ≤ x2).

Example
Input

10 70 100 100 25

Output

99 33

Input

300 500 1000 1000 300

Output

1000 0

Input

143 456 110 117 273

Output

76 54

Note

In the second sample the hot water tap shouldn't be opened, but the cold water tap should be opened at full capacity in order to fill the bath in the quickest way possible.

以下为Accepted代码

#include <bits/stdc++.h>
#define ULL unsigned long long
#define LL long long

using namespace std;

int main(){
    LL t1, t2, x1, x2, t0, res_x1, res_x2;
    double t, ct;
    while(scanf("%lld %lld %lld %lld %lld", &t1, &t2, &x1, &x2, &t0) != EOF){
        ct = 1e104;
        while(x1 >= 0 && x2 >= 0){
            t = (double)(t1*x1 + t2*x2)/(x1+x2);
            if(t < t0){
                x1--;
                continue;
            }
            if(t < ct){
                ct = t;
                res_x1 = x1;
                res_x2 = x2;
            }
            x2--;
        }
        printf("%lld %lld\n", res_x1, res_x2);
    }
    return 0;
}
题目 `Codeforces 2128F Strict Triangle` 是一道较为复杂的计算几何与构造题。题目要求构造一个满足特定条件的三角形,并根据给定的点集判断是否存在这样的三角形。下面将从题目解析、解题思路和代码实现三个方面进行说明。 ### 题目大意 给定平面上 $n$ 个点,要求判断是否存在三个点 $A, B, C$,使得: 1. 三角形 $ABC$ 是非退化的(即面积不为零); 2. 满足 $\angle ABC$ 是严格锐角(即小于 $90^\circ$)。 如果存在这样的三角形,输出任意一组满足条件的三点;否则,输出 `NO`。 ### 解题思路 #### 1. 几何性质分析 判断一个角是否为锐角,可以通过向量内积的方式进行判断。设三点 $A, B, C$ 构成三角形,其中 $B$ 为角的顶点,则: $$ \vec{BA} \cdot \vec{BC} = |\vec{BA}| \cdot |\vec{BC}| \cdot \cos(\theta) $$ 若 $\theta < 90^\circ$,则 $\cos(\theta) > 0$,因此只需要判断 $\vec{BA} \cdot \vec{BC} > 0$。 #### 2. 算法选择 - 枚举所有点对 $B$ 作为角的顶点; - 对于每个点 $B$,枚举所有点 $A, C$,并计算 $\vec{BA} \cdot \vec{BC} > 0$; - 同时确保三点不共线(即三角形面积不为零)。 #### 3. 时间复杂度优化 由于 $n$ 最大为 $1000$,直接三重循环会导致 $O(n^3)$ 的时间复杂度,这在最坏情况下会超时。因此需要优化: - 固定点 $B$,枚举所有其他点作为 $A$; - 对于每个 $A$,再枚举所有点 $C$,但跳过 $A=C$ 或 $B=C$ 的情况; - 利用向量点积的性质快速判断。 这样复杂度为 $O(n^2)$,对于 $n=1000$ 可以接受。 ### 代码实现 以下是一个完整的 AC 代码实现,用于判断是否存在满足条件的三角形并输出结果: ```cpp #include <bits/stdc++.h> using namespace std; typedef long long ll; const int MAXN = 1005; struct Point { ll x, y; } points[MAXN]; ll dot(Point a, Point b, Point c, Point d) { ll dx1 = b.x - a.x; ll dy1 = b.y - a.y; ll dx2 = d.x - c.x; ll dy2 = d.y - c.y; return dx1 * dx2 + dy1 * dy2; } ll cross(Point a, Point b, Point c, Point d) { ll dx1 = b.x - a.x; ll dy1 = b.y - a.y; ll dx2 = d.x - c.x; ll dy2 = d.y - c.y; return dx1 * dy2 - dx2 * dy1; } int main() { int n; cin >> n; for (int i = 0; i < n; ++i) { cin >> points[i].x >> points[i].y; } for (int b = 0; b < n; ++b) { for (int a = 0; a < n; ++a) { if (a == b) continue; for (int c = a + 1; c < n; ++c) { if (c == b) continue; // Check angle at b ll dot_product = dot(points[b], points[a], points[b], points[c]); if (dot_product > 0) { ll area = cross(points[a], points[b], points[b], points[c]); if (area != 0) { cout << "YES" << endl; cout << a + 1 << " " << b + 1 << " " << c + 1 << endl; return 0; } } } } } cout << "NO" << endl; return 0; } ``` ### 说明 - `dot()` 函数用于计算两个向量的点积; - `cross()` 函数用于计算两个向量的叉积,判断是否共线; - 枚举所有可能的点 $B$,并遍历其他点 $A, C$,判断是否满足锐角条件; - 若找到符合条件的三角形,立即输出并终止程序。 ### 时间与空间复杂度 - 时间复杂度:$O(n^2)$; - 空间复杂度:$O(n)$,仅存储点集。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值