UNIQUE VISION Programming Contest 2024 Christmas (AtCoder Beginner Contest 385) 题解记录A~F

开个新坑,感觉Atcoder的题目还是比较有意思的,有点启发意义吧。

A.Equally

题面:
您将获得三个整数 A,B,C 。确定是否可以将这三个整数分成两个或多个组,以使这些组的总和相等。
约束:
1≤A,B,C≤1000
输出:
如果可以 A,B,C 分成两个或多个总和相等的组,请打印 Yes;否则,打印 No。
思路:签到题啦,随便组合一下就好了

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#include<functional>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//#include<bits/stdc++.h>
// #include <unordered_map>
#define ll                  long long
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
using namespace std;
//using namespace __gnu_pbds;
mt19937 rnd(time(0));
// const ll p=13;
const ll mod = 1e9+7;
ll ksm(ll x, ll y)
{
	ll ans = 1;
	while (y)
	{
		if (y & 1)
		{
			ans = ans % mod * (x % mod) % mod;
		}
		x = x % mod * (x % mod) % mod;
		y >>= 1;
	}
	return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
	if (y == 0)
		return x;

	else
		return gcd(y, x % y);
}
void fio()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
}
struct s
{
	ll l, r;
	bool operator<(const s& a)const
	{
		if (l != a.l)
			return l < a.l;
		else return r < a.r;
	}
};
struct cmp
{
	bool operator()(const s& a, const s& b)const
	{
	}
};
int main()
{
	fio();
	ll a,b,c;
	cin>>a>>b>>c;
	if(a==b+c||b==a+c||c==a+b||(a==b&&b==c))cout<<"Yes"<<endl;
	else 
	cout<<"No"<<endl;	
	return 0;
}

B.Santa Claus 1

题面:
有一个 \(H\)\(W\) 列的网格。让 \((i, j)\) 表示从顶部数第 \(i\) 行,从左侧数第 \(j\) 列的单元格。

如果 \(S_{i, j}\) 是 #,那么单元格 \((i, j)\) 是不可通行的;如果它是 .,单元格是可通行的并且没有房子;如果它是 @,单元格是可通行的并且包含一个房子。

最初,圣诞老人在单元格 \((X, Y)\)。他将根据字符串 \(T\) 进行操作,如下所示:

\(|T|\) 表示字符串 \(T\) 的长度。对于 \(i=1,2,\ldots,|T|\),他按照以下方式移动。
\((x, y)\) 表示他当前所在的单元格。
如果 \(T_i\) 是 u 并且单元格 \((x-1, y)\) 是可通行的,移动到单元格 \((x-1, y)\)
如果 \(T_i\) 是 d 并且单元格 \((x+1, y)\) 是可通行的,移动到单元格 \((x+1, y)\)
如果 \(T_i\) 是 l 并且单元格 \((x, y-1)\) 是可通行的,移动到单元格 \((x, y-1)\)
如果 \(T_i\) 是 r 并且单元格 \((x, y+1)\) 是可通行的,移动到单元格 \((x, y+1)\)
否则,停留在单元格 \((x, y)\)
找出他完成所有操作后所在的单元格,以及他在操作过程中经过或到达的不同房子的数量。如果同一个房子经过多次,只计算一次。
约束:
\(3 \leq H, W \leq 100\)
\(1 \leq X \leq H\)
\(1 \leq Y \leq W\)
所有给定的数字都是整数。
每个 \(S_{i, j}\) 可以是 #,. 或 @ 中的一个。
对于所有 \(1 \leq i \leq H\)\(S_{i, 1}\)\(S_{i, W}\) 都是 #。
对于所有 \(1 \leq j \leq W\)\(S_{1, j}\)\(S_{H, j}\) 都是 #。
$S_{X, Y} = .

\(T\) 是一个长度至少为 1 且最多为 \(10^4\) 的字符串,由 U,D,L,R 组成。
输出:
\((X, Y)\) 表示他完成所有操作后所在的单元格,\(C\) 表示他在操作过程中经过或到达的不同房子的数量。按顺序打印 \(X, Y, C\),它们之间用空格分隔。
思路:数据范围很小,直接模拟一遍即可,对于走过的房子标记一下再考虑是否计数就好了

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#include<functional>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//#include<bits/stdc++.h>
// #include <unordered_map>
#define ll                  long long
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
using namespace std;
//using namespace __gnu_pbds;
mt19937 rnd(time(0));
// const ll p=13;
const ll mod = 1e9+7;
ll ksm(ll x, ll y)
{
	ll ans = 1;
	while (y)
	{
		if (y & 1)
		{
			ans = ans % mod * (x % mod) % mod;
		}
		x = x % mod * (x % mod) % mod;
		y >>= 1;
	}
	return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
	if (y == 0)
		return x;

	else
		return gcd(y, x % y);
}
void fio()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
}
struct s
{
	ll l, r;
	bool operator<(const s& a)const
	{
		if (l != a.l)
			return l < a.l;
		else return r < a.r;
	}
};
struct cmp
{
	bool operator()(const s& a, const s& b)const
	{
	}
};
ll n,m,x,y;
string f[250];
ll ans=0;
bool vis[250][250];
void ck(char c)
{
	if(c=='U'&&x-1>=1&&f[x-1][y]!='#')
	{
		x--;
		if(f[x][y]=='@'&&vis[x][y]==0)ans++;
		vis[x][y]=1;
	}
	else if(c=='D'&&x+1<=n&&f[x+1][y]!='#')
	{
		x++;
		if(f[x][y]=='@'&&vis[x][y]==0)ans++;
		vis[x][y]=1;
	}
	else if(c=='L'&&y-1>=1&&f[x][y-1]!='#')
	{
		y--;
		if(f[x][y]=='@'&&vis[x][y]==0)ans++;
		vis[x][y]=1;
	}
	else if(c=='R'&&y+1<=m&&f[x][y+1]!='#')
	{
		y++;
		if(f[x][y]=='@'&&vis[x][y]==0)ans++;
		vis[x][y]=1;
	}
}
int main()
{
	fio();
	cin>>n>>m>>x>>y;
	string k;
	for(ll i=1;i<=n;i++)
	{
		cin>>f[i];
		f[i]='0'+f[i];
	}
	cin>>k;
	for(ll i=0;i<k.size();i++)
	{
		ck(k[i]);
	}
	cout<<x<<" "<<y<<" ";
	cout<<ans<<endl;
	return 0;
}

C.Illuminate Buildings

题面:
\(N\) 座建筑物按相等的间隔排成一行。从前面数第 \(i\) 座建筑物的高度是 \(H_i\)

你想用照明装饰其中一些建筑物,以便满足以下两个条件:

选择的建筑物都有相同的高度。
选择的建筑物按相等的间隔排列。
你最多可以选择多少座建筑物?如果你选择恰好一座建筑物,这被认为满足条件。
约束:
\(1 \leq N \leq 3000\)
\(1 \leq H_i \leq 3000\)
所有输入值都是整数。
输出:
输出答案
思路:由于N的最大值为3000,所以考虑了暴力,三重循环,最外面枚举长度,第二层枚举起点,第三层遍历等差点,由于第二层和第三层时间复杂度总和为调和级数级别左右,所以总时间复杂度大致为\(n^{2}logn\)左右,不会TLE

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#include<functional>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//#include<bits/stdc++.h>
// #include <unordered_map>
#define ll                  long long
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
using namespace std;
//using namespace __gnu_pbds;
mt19937 rnd(time(0));
// const ll p=13;
const ll mod = 1e9+7;
ll ksm(ll x, ll y)
{
	ll ans = 1;
	while (y)
	{
		if (y & 1)
		{
			ans = ans % mod * (x % mod) % mod;
		}
		x = x % mod * (x % mod) % mod;
		y >>= 1;
	}
	return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
	if (y == 0)
		return x;

	else
		return gcd(y, x % y);
}
void fio()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
}
struct s
{
	ll l, r;
	bool operator<(const s& a)const
	{
		if (l != a.l)
			return l < a.l;
		else return r < a.r;
	}
};
struct cmp
{
	bool operator()(const s& a, const s& b)const
	{
	}
};
ll n,m,x,y;
string f[250];
ll ans=0;
bool vis[250][250];
void ck(char c)
{
	if(c=='U'&&x-1>=1&&f[x-1][y]!='#')
	{
		x--;
		if(f[x][y]=='@'&&vis[x][y]==0)ans++;
		vis[x][y]=1;
	}
	else if(c=='D'&&x+1<=n&&f[x+1][y]!='#')
	{
		x++;
		if(f[x][y]=='@'&&vis[x][y]==0)ans++;
		vis[x][y]=1;
	}
	else if(c=='L'&&y-1>=1&&f[x][y-1]!='#')
	{
		y--;
		if(f[x][y]=='@'&&vis[x][y]==0)ans++;
		vis[x][y]=1;
	}
	else if(c=='R'&&y+1<=m&&f[x][y+1]!='#')
	{
		y++;
		if(f[x][y]=='@'&&vis[x][y]==0)ans++;
		vis[x][y]=1;
	}
}
ll a[250000];
int main()
{
	fio();
	ll n;
	cin>>n;
	for(ll i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	ll ans=0;
	for(ll i=1;i<=n;i++)
	{
		for(ll j=1;j<=n;j++)
		{
			ll cnt=0;
			for(ll u=j;u<=n;u+=i)
			{
				if(a[u]==a[j])
				{
					cnt++;
				}
				else break;
			}
			ans=max(ans,cnt);
		}
	}
	cout<<ans<<endl;
	return 0;
}

D.Santa Claus 2

题面:
在二维平面上有 \(N\) 个房子,位于点 \((X_1, Y_1), \ldots, (X_N, Y_N)\)。最初,圣诞老人位于点 \((S_x, S_y)\)。他将根据序列 \((D_1, C_1), \ldots, (D_M, C_M)\) 进行操作,如下所示:

按顺序对 \(i = 1, 2, \ldots, M\) 进行操作,他的移动方式如下:
\((x, y)\) 为他当前所在的点。
如果 \(D_i\) 是 u,从 \((x, y)\) 沿直线移动到 \((x, y + C_i)\)
如果 \(D_i\) 是 d,从 \((x, y)\) 沿直线移动到 \((x, y - C_i)\)
如果 \(D_i\) 是 l,从 \((x, y)\) 沿直线移动到 \((x - C_i, y)\)
如果 \(D_i\) 是 r,从 \((x, y)\) 沿直线移动到 \((x + C_i, y)\)
找出他完成所有操作后所在的点,以及他在操作过程中经过或到达的不同房子的数量。如果同一个房子经过多次,只计算一次。
约束:
\(1 \leq N \leq 2 \times 10^5\)
\(1 \leq M \leq 2 \times 10^5\)
\(-10^9 \leq X_i, Y_i \leq 10^9\)
点对 \((X_i, Y_i)\) 是互不相同的。
\(-10^9 \leq S_x, S_y \leq 10^9\)
\((S_x, S_y)\) 处没有房子。
每个 \(D_i\) 可以是 u(上)、d(下)、l(左)、r(右)中的一个。
\(1 \leq C_i \leq 10^9\)
所有输入数字都是整数。
输出:
\((X, Y)\) 表示他完成所有操作后的点,\(C\) 表示经过或到达的不同房子的数量。按顺序打印 \(X, Y, C\),它们之间用空格分隔。
思路:其实就是优化暴力模拟,这里用set优化,分别存横坐标对应的纵坐标,纵坐标对应的横坐标。首先注意数据范围大必须得离散化,多维set的第一维就是离散化后的值,而存的数字必须为非离散化数字,其实每次移动,都是移动一段区间的,所以可以对x,y,中不变的数字所对应的set进行二分,然后while循环,直到没有点落在这个区间内就好了,记得删点时,把另一个set中的值删掉,其实时间复杂度也就\(n*logn*logn\)左右吧

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#include<functional>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//#include<bits/stdc++.h>
// #include <unordered_map>
#define ll                  long long
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
using namespace std;
//using namespace __gnu_pbds;
mt19937 rnd(time(0));
// const ll p=13;
const ll mod = 1e9+7;
ll ksm(ll x, ll y)
{
	ll ans = 1;
	while (y)
	{
		if (y & 1)
		{
			ans = ans % mod * (x % mod) % mod;
		}
		x = x % mod * (x % mod) % mod;
		y >>= 1;
	}
	return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
	if (y == 0)
		return x;

	else
		return gcd(y, x % y);
}
void fio()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
}
struct s
{
	ll l, r;
	bool operator<(const s& a)const
	{
		if (l != a.l)
			return l < a.l;
		else return r < a.r;
	}
};
struct cmp
{
	bool operator()(const s& a, const s& b)const
	{
	}
};
ll a[250000];
set<ll>r[550000],l[550000];
int main()
{
	fio();
	ll n,m,x,y;
	cin>>n>>m>>x>>y;
	map<ll,ll>q;
	ll cnt=0;
	for(ll i=1;i<=n;i++)
	{
		ll x1,y1;
		cin>>x1>>y1;
		if(q[x1]==0)q[x1]=++cnt;
		if(q[y1]==0)q[y1]=++cnt;
		l[q[y1]].insert(x1);
		r[q[x1]].insert(y1);
	}
	ll ans=0;
	while(m--)
	{
		char f;
		cin>>f;ll op;
		cin>>op;
		if(f=='L')
		{
			if(l[q[y]].size()>0)//x~x-op
			{
				while(1)
				{
					auto j=l[q[y]].lower_bound(x-op);
					if(j==l[q[y]].end())break;
					else 
					{
						if(*j>x)break;
						r[q[*j]].erase(y);
						l[q[y]].erase(*j);
						ans++;
					}
				}
			}
			x-=op;
		}
		else if(f=='R')//x~x+op
		{
			if(l[q[y]].size()>0)
			{
				while(1)
				{
					auto j=l[q[y]].lower_bound(x);
					if(j==l[q[y]].end()||*j>x+op)break;
					r[q[*j]].erase(y);
					l[q[y]].erase(*j);
						ans++;
				}
			}
			x+=op;
		}
		else if(f=='D')//y-op~y
		{
			if(r[q[x]].size()>0)
			{
				while(1)
				{
					auto j=r[q[x]].lower_bound(y-op);
					if(j==r[q[x]].end()||*j>y)break;
					l[q[*j]].erase(x);
					r[q[x]].erase(*j);ans++;
				}
			}
			y-=op;
		}
		else 
		{
			if(r[q[x]].size()>0)//y~y+op
			{
				while(1)
				{
					auto j=r[q[x]].lower_bound(y);
					if(j==r[q[x]].end()||*j>y+op)break;
					l[q[*j]].erase(x);
					r[q[x]].erase(*j);ans++;
				}
			}
			y+=op;
		}
	}
	cout<<x<<" "<<y<<" ";
	cout<<ans<<endl;
	return 0;
}

E.Snowflake Tree

“雪花树”定义为可以通过以下步骤生成的树:

选择正整数 \(x, y\)
准备一个顶点。
准备 \(x\) 个更多的顶点,并将它们每一个都连接到步骤 2 中准备的顶点上。
对于步骤 3 中准备的每一个 \(x\) 个顶点,附上 \(y\) 个叶子。
下图展示了一个 \(x=4, y=2\) 的雪花树。步骤 2、3、4 中准备的顶点分别用红色、蓝色和绿色表示。

给定一个有 \(N\) 个顶点的树 \(T\)。顶点编号从 1 到 \(N\),第 \(i\) 条边(\(i = 1, 2, \ldots, N - 1\))连接顶点 \(u_i\)\(v_i\)

考虑删除 \(T\) 中的一个或多个顶点及其相邻的边,使得剩余的图成为一个单一的雪花树。找到必须删除的最小顶点数。在这个问题的约束条件下,总是可以将 \(T\) 转换为一个雪花树。
约束:
\(3 \leq N \leq 3 \times 10^5\)
\(1 \leq u_i < v_i \leq N\)
给定的图是一个树。
所有输入值都是整数。
输出:
输出答案
思路:如何找中心点呢?试着遍历所有点作为中心点!首先先dfs一遍进行sz记录,然后第二遍dfs得考虑两个事:1.统计答案,2.实现根的变化,根的变化好解决,无非就是sz的变换。统计答案呢?思考这是一棵树,所以我可以先遍历一遍把必须要删除的点进行统计(中心点往外面扩大3层及以后的点都不要了),然后对于可能的答案点进行去重统计,随后排个序,一个答案被选定后,比他小的答案的所有点都得被删除,比他大的点必须减少到刚好为这个答案,所以前缀和预处理一遍,在倒序一遍就可以得出答案。ans取个min就可以了

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#include<functional>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//#include<bits/stdc++.h>
// #include <unordered_map>
#define ll                  long long
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
using namespace std;
//using namespace __gnu_pbds;
mt19937 rnd(time(0));
// const ll p=13;
const ll mod = 1e9+7;
ll ksm(ll x, ll y)
{
	ll ans = 1;
	while (y)
	{
		if (y & 1)
		{
			ans = ans % mod * (x % mod) % mod;
		}
		x = x % mod * (x % mod) % mod;
		y >>= 1;
	}
	return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
	if (y == 0)
		return x;

	else
		return gcd(y, x % y);
}
void fio()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
}
struct s
{
	ll l, r;
	bool operator<(const s& a)const
	{
		if (l != a.l)
			return l < a.l;
		else return r < a.r;
	}
};
struct cmp
{
	bool operator()(const s& a, const s& b)const
	{
	}
};
vector<ll>g[450000];
ll sz[450000];
ll a[450000];
ll pre[450000];
int main()
{
	fio();
	ll n;
	cin>>n;
	for(ll i=1;i<n;i++)
	{
		ll l,r;
		cin>>l>>r;
		g[l].push_back(r);
		g[r].push_back(l);
	}
	function<void(ll,ll)>df=[&](ll x,ll f)
	{
		sz[x]=1;
		for(auto j:g[x])
		{
			if(j==f)continue;
			else df(j,x);
			sz[x]+=sz[j];
		}
	};
	df(1,0);
	ll ans=1e18;
	map<ll,ll>k;
	function<void(ll,ll)>dfs=[&](ll x,ll f)
	{
		ll l=0;
		ll z=1e18;
		ll cnt=0;
		k.clear();
		for(auto j:g[x])
		{
			cnt+=sz[j]-1-(g[j].size()-1);//基本费用
			if(k[g[j].size()-1]==0)
			{
				l++;
				a[l]=g[j].size()-1;
			}
			k[g[j].size()-1]++;
		}
		sort(a+1,a+1+l);
		for(ll i=1;i<=l;i++)
		{
			pre[i]=pre[i-1]+k[a[i]]*(a[i]+1);
		}
		ll op=0;
		ll uo=0;
		for(ll i=l;i>=1;i--)
		{
			ans=min(ans,pre[i-1]+op+cnt);
			uo+=k[a[i]];//个数,
			op+=uo*a[i]-uo*a[i-1];
		}
		//if(x==2)cout<<sz[3]<<endl;
		for(auto j:g[x])
		{
			if(j==f)continue;
			sz[x]-=sz[j];
			sz[j]+=sz[x];
			dfs(j,x);
			sz[j]-=sz[x];
			sz[x]+=sz[j];
		}
	};
	dfs(1,0);
	cout<<ans<<endl;
}

F.Visible Buildings

题面:
在数轴上有 \(N\) 座编号为 1 到 \(N\) 的建筑物。第 \(i\) 座建筑物位于坐标 \(X_i\),高度为 \(H_i\)。除了高度以外,其他方向的尺寸可以忽略不计。

从坐标为 \(x\)、高度为 \(h\) 的点 \(P\) 出发,如果存在建筑物 \(i\) 上的点 \(Q\),使得线段 \(PQ\) 不与任何其他建筑物相交,则认为建筑物 \(i\) 是可见的。

找出在坐标 0 处无法看到所有建筑物的最大高度。高度必须是非负的;如果在坐标 0 的高度 0 处可以看到所有建筑物,则报告 -1。
约束:
\(1 \leq N \leq 2 \times 10^5\)
\(1 \leq X_1 < X_2 < \cdots < X_N \leq 10^9\)
\(1 \leq H_i \leq 10^9\)
所有输入值均为整数。
输出:
思路:其实就是两个相邻点的最大斜率就是了,在循环过程中加个数字判断下斜率是否是递增的,如果是的话就得输出-1,否则输出斜率最大值.
给出证明,如果一个点和前面非相邻点斜率比这个点和前面的点斜率更大,那么前面非相邻的点和前面的点的斜率将会更大
反之越小也是同理。所以答案即为极限值,因为可以有误差,所以输出这个点的值就可。默认多了个无穷小。

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#include<functional>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//#include<bits/stdc++.h>
// #include <unordered_map>
#define ll                  long long
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
using namespace std;
//using namespace __gnu_pbds;
mt19937 rnd(time(0));
// const ll p=13;
const ll mod = 1e9+7;
ll ksm(ll x, ll y)
{
	ll ans = 1;
	while (y)
	{
		if (y & 1)
		{
			ans = ans % mod * (x % mod) % mod;
		}
		x = x % mod * (x % mod) % mod;
		y >>= 1;
	}
	return ans % mod % mod;
}
ll gcd(ll x, ll y)
{
	if (y == 0)
		return x;

	else
		return gcd(y, x % y);
}
void fio()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
}
struct s
{
	ll x,h;
	bool operator<(const s& a)const
	{
		if (x != a.x)
			return x < a.x;
		else return h < a.h;
	}
}p[250000];
struct cmp
{
	bool operator()(const s& a, const s& b)const
	{
	}
};
int main()
{
	fio();
	ll n;
	cin>>n;
	ll uo=0;
	ll cn1,cn2;
	cn1=1,cn2=0;
	ll pd=0;
	// ll pd=0;
	// for(ll i=1;i<=n;i++)
	// {
	// 	cin>>p[i].x>>p[i].h;
	// 	ll u=p[i].x,z=p[i].h;
	// 	ll k=gcd(u,z);
	// 	u/=k,z/=k;
	// 	ll d=gcd(u,cn1);
	// 	cn1=u/d*cn1,cn2=u/d*cn2;
	// 	u=cn1,z=cn1/u*z;
	// 	if(z<=cn2)
	// 	pd=1;
	// 	cn1=u,cn2=z;
	// 	k=gcd(cn1,cn2);
	// 	cn1/=k,cn2/=k;
	// } 
	for(ll i=1;i<=n;i++)cin>>p[i].x>>p[i].h;
	long double ans=0;
	p[0].x=p[0].h=0;
	long double co=-1;
	for(ll i=1;i<=n;i++)//y=k(x-p[i].x)+p[i].h
	{
		long double k=(long double)(p[i].h-p[i-1].h)/(long double)(p[i].x-p[i-1].x);
		if(co>=(long double)p[i].h/(long double)p[i].x)
		pd=1;
		co=(long double)p[i].h/(long double)p[i].x;
		//printf("%.8Lf\n",co);
		ans=max(ans,p[i].h-k*p[i].x);
	}
	if(pd==0)
	cout<<-1<<endl;
	else 
	printf("%.18Lf\n",ans);
}


posted @ 2024-12-22 02:38  长皆  阅读(55)  评论(0)    收藏  举报