Wooden Toy Festival题解
思路 : : :
二分,二分距离,首先肯定要排序,然后这题还得去一下重(因为题目说了"雕刻师们都是非常熟练的人,可以同时为不同的人完成订单",那当然要让他们同时做一种就行了)。
然后还要找出区间内的三个点,能够覆盖整个区间即可满足题意。
找最小覆盖区间的距离,在于找最小距离,也就可以二分距离,找出三段 2 ∗ d 2*d 2∗d的长度可以覆盖全部区间的最小 d d d,也就是最后的答案。
上代码:
#include <iostream> // 基本入出力ストリーム
#include <algorithm> // 一般的なアルゴリズム(ソート、ルックアップ、やり直し、二分ルックアップなど)
#include <vector> // 動的配列(スペースが足りないと自動的に拡張されます)
#include <queue> // スタック(先に入って先に出ます)
#include <stack> // スタック(先に入ってから出ます)
#include <set> // 集合(反復しない順序)です
#include <map> // キー値対コンテナ(マッピング)
#include <list> // 両方向リスト
#include <math.h> // すうがくかんすう
#include <functional> // 通用的函数绑定和调用机制一般的なバインディングと呼び出しの仕組み#define endl '\n'
#define pii pair<int, int>
#define pdd pair<double, double>
#define fi first
#define se second
#define pb push_back
#define eb emplace_backusing namespace std;const int inf = 1e9 + 7;
const int mod = 998244353;
const int N = 2e5 + 10, M = N << 1;int n;
long long a[N];bool check(int x)//检查一下,亲
//找出三段2*d的长度可以覆盖全部区间的最小d,也就是最后的答案。
{int cnt = 0;//数个数int in = 1;for(int i = 2; i <= n; i++){if(a[in] + 2 * x < a[i]){in = i;cnt++;}}return cnt < 3;
}
void solve() {cin >> n;set<long long> s;//自动排序 / 自动去重 -> setfor(int i = 1; i <= n; i++) {//将数据导入到 set 集合 / long long 数组中cin >> a[i];s.insert(a[i]);}if(s.size() <= 3) {//不用任何时间:|x-y|(x==y)=0cout << 0 << endl;return;//直接下一次}sort(a + 1, a + 1 + n);//数组内排序int l = 0;//看好了,我要开始二分咯int r = a[n];//最后一个while(l < r) {int mid = (l + r) >> 1;if(check(mid)) //检查一下,亲r = mid;//往左缩else l = mid + 1;//a……往右缩}cout << l << endl;//答案\(*^▽^*)/
}signed main() {ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int t;cin >> t; // 非多组测试数据请注释该行while(t--) solve();return 0;
}
已AC请放心食用