题意

不想写。

题解

场上想了 1h+ 无果,一到场外就口胡出来了,我真是个 sb。

首先注意到如果 \(t\) 满足条件那么 \(t+1\) 也会满足,所以答案具有单调性,可以二分,于是现在只需要考虑对于某个特定的 \(t\) 能否满足。

注意到对于平面上的 \(u,v,w\) 三个点来说,如果 \(u\) 能到 \(v\),\(v\) 能到 \(w\) 那么 \(u\) 一定能到 \(w\)。

既然这个可达性是可以传递的,那么可以用一个并查集来将相互到的点缩成一个连通块。

如果连通块个数为 \(1\) 那么一定可以,大于 \(4\) 就一定不行,剩下的情况讨论一下。

如果连通块个数为 \(2\),那么只需要找出两个分属不同连通块的点,然后看看加一个点能不能使得这两个点互相可达即可。

如果连通块个数为 \(3\),那么只需要找出一条线段和一个点,线段的两个端点和选出来的点分属三个不同的连通块。这个时候注意到加的那个点是已经确定了的,所以直接判断一下即可。

如果连通块个数为 \(4\),那么只需要找出两条相交的线段,四个端点分属不同的连通块。这个时候新加的那个点就是线段的端点。简单判断一下可达性即可。

本题代码细节比较多,建议配合代码理解。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll MAXN=1e3+51;
struct Tuple{
ll x,y;
inline bool operator <(const Tuple &rhs)const
{
return this->x==rhs.x?this->y<rhs.y:this->x<rhs.x;
}
};
map<ll,vector<Tuple>>row,col;
ll n,totr,totc,l,r,mid,res=-1;
ll ffa[MAXN],x[MAXN],y[MAXN],bel[MAXN],rows[MAXN],cols[MAXN];
inline ll read()
{
register ll num=0,neg=1;
register char ch=getchar();
while(!isdigit(ch)&&ch!='-')
{
ch=getchar();
}
if(ch=='-')
{
neg=-1;
ch=getchar();
}
while(isdigit(ch))
{
num=(num<<3)+(num<<1)+(ch-'0');
ch=getchar();
}
return num*neg;
}
inline ll find(ll x)
{
return x==ffa[x]?x:ffa[x]=find(ffa[x]);
}
inline void merge(ll x,ll y)
{
ll fx=find(x),fy=find(y);
if(fx!=fy)
{
ffa[fy]=fx;
}
}
inline ll check(ll mid)
{
ll blk=0,p,q,r,s,lx,rx;
for(register int i=1;i<=n;i++)
{
ffa[i]=i;
}
for(register int i=1;i<=n;i++)
{
for(register int j=i+1;j<=n;j++)
{
if(x[i]==x[j]&&abs(y[i]-y[j])<=mid)
{
merge(i,j);
}
if(y[i]==y[j]&&abs(x[i]-x[j])<=mid)
{
merge(i,j);
}
}
}
for(register int i=1;i<=n;i++)
{
blk+=(find(i)==i);
}
if(blk==1)
{
return 1;
}
if(blk>4)
{
return 0;
}
for(register int i=1;i<=n;i++)
{
bel[i]=ffa[i];
}
if(blk==2)
{
for(register int i=1;i<=n;i++)
{
for(register int j=1;j<=n;j++)
{
if(bel[i]==bel[j])
{
continue;
}
if(x[i]==x[j]&&abs(y[i]-y[j])<=2*mid)
{
return 1;
}
if(y[i]==y[j]&&abs(x[i]-x[j])<=2*mid)
{
return 1;
}
if(abs(x[i]-x[j])<=mid&&abs(y[i]-y[j])<=mid)
{
return 1;
}
}
}
return 0;
}
if(blk==3)
{
vector<Tuple>v;
for(register int i=1;i<=totr;i++)
{
for(register int j=1;j<row[rows[i]].size();j++)
{
p=row[rows[i]][j-1].y,q=row[rows[i]][j].y;
bel[p]!=bel[q]?v.push_back((Tuple){p,q}):(void)1;
}
}
for(register int i=1;i<=totc;i++)
{
for(register int j=1;j<col[cols[i]].size();j++)
{
p=col[cols[i]][j-1].y,q=col[cols[i]][j].y;
bel[p]!=bel[q]?v.push_back((Tuple){p,q}):(void)1;
}
}
for(register int i=0;i<v.size();i++)
{
p=v[i].x,q=v[i].y;
for(register int j=1;j<=n;j++)
{
if(bel[p]==bel[j]||bel[q]==bel[j])
{
continue;
}
if(x[p]==x[q])
{
lx=min(y[p],y[q]),rx=max(y[p],y[q]);
if(y[j]>lx&&y[j]<rx&&abs(x[j]-x[p])<=mid)
{
if(abs(y[j]-y[p]<=mid)&&abs(y[j]-y[q])<=mid)
{
return 1;
}
}
}
else
{
lx=min(x[p],x[q]),rx=max(x[p],x[q]);
if(x[j]>lx&&x[j]<rx&&abs(y[j]-y[p])<=mid)
{
if(abs(x[j]-x[p]<=mid)&&abs(x[j]-x[q])<=mid)
{
return 1;
}
}
}
}
}
return 0;
}
if(blk==4)
{
vector<Tuple>vx,vy;
for(register int i=1;i<=totr;i++)
{
for(register int j=1;j<row[rows[i]].size();j++)
{
p=row[rows[i]][j-1].y,q=row[rows[i]][j].y;
bel[p]!=bel[q]?vx.push_back((Tuple){p,q}):(void)1;
}
}
for(register int i=1;i<=totc;i++)
{
for(register int j=1;j<col[cols[i]].size();j++)
{
p=col[cols[i]][j-1].y,q=col[cols[i]][j].y;
bel[p]!=bel[q]?vy.push_back((Tuple){p,q}):(void)1;
}
}
for(register int i=0;i<vx.size();i++)
{
for(register int j=0;j<vy.size();j++)
{
p=vx[i].x,q=vx[i].y,r=vy[j].x,s=vy[j].y,lx=x[p],rx=y[r];
if(bel[p]==bel[r]||bel[p]==bel[s])
{
continue;
}
if(bel[q]==bel[r]||bel[q]==bel[s])
{
continue;
}
if(y[r]<=min(y[p],y[q])||y[r]>=max(y[p],y[q]))
{
continue;
}
if(x[p]<=min(x[r],x[s])||x[p]>=max(x[r],x[s]))
{
continue;
}
if(abs(rx-y[p])<=mid&&abs(rx-y[q])<=mid)
{
if(abs(lx-x[r])<=mid&&abs(lx-x[s])<=mid)
{
return 1;
}
}
}
}
return 0;
}
}
int main()
{
n=read(),r=2e9;
for(register int i=1;i<=n;i++)
{
rows[++totr]=x[i]=read(),cols[++totc]=y[i]=read();
row[x[i]].push_back((Tuple){y[i],i});
col[y[i]].push_back((Tuple){x[i],i});
}
sort(rows+1,rows+totr+1),sort(cols+1,cols+totc+1);
totr=unique(rows+1,rows+totr+1)-rows-1;
totc=unique(cols+1,cols+totc+1)-cols-1;
for(register int i=1;i<=totr;i++)
{
sort(row[rows[i]].begin(),row[rows[i]].end());
}
for(register int i=1;i<=totc;i++)
{
sort(col[cols[i]].begin(),col[cols[i]].end());
}
while(l<=r)
{
mid=(l+r)>>1;
check(mid)?res=mid,r=mid-1:l=mid+1;
}
printf("%d\n",res);
}

CodeForces 1419F Rain of Fire的更多相关文章

  1. Codeforces 988F Rain and Umbrellas(DP)

    题目链接:http://codeforces.com/contest/988/problem/F 题目大意: 有三个整数a,n,m,a是终点坐标,给出n个范围(l,r)表示这块区域下雨,m把伞(p,w ...

  2. Codeforces Round #436 E. Fire(背包dp+输出路径)

    题意:失火了,有n个物品,每个物品有价值pi,必须在时间di前(小于di)被救,否则就要被烧毁.救某个物 品需要时间ti,问最多救回多少价值的物品,并输出救物品的顺序. Examples Input ...

  3. Codeforces 988F. Rain and Umbrellas

    解题思路:动态规划 遍历点i,如果从前一个点i-1走到这个点i不需要伞,则疲劳值不变dp[i] = dp[i-1]. 如果前一个点i-1走到这一个点i需要伞,则从前面找一把伞. 即遍历前面的每个点j, ...

  4. CodeForces 题目乱做

    是个补题记录. 1419 除了 F 场上都过了. CF1419A Digit Game 这题好多人 FST 啊-- 考虑如果串长为奇数那么最后操作的肯定是第一个人,串长为偶数的最后操作的肯定是第二个, ...

  5. little alchemy攻略

    一个造物游戏: acidrain=rain+smoke airlplain=metal+bird alcohol=fruit+time algae=plant+water allergy=dust+h ...

  6. [Codeforces 864E]Fire

    Description Polycarp is in really serious trouble — his house is on fire! It's time to save the most ...

  7. Codeforces Round #486 (Div. 3) F. Rain and Umbrellas

    Codeforces Round #486 (Div. 3) F. Rain and Umbrellas 题目连接: http://codeforces.com/group/T0ITBvoeEx/co ...

  8. D. Frets On Fire 【二分,前缀和】 (Codeforces Global Round 2)

    题目传送门:http://codeforces.com/contest/1119/problem/D D. Frets On Fire time limit per test 1.5 seconds ...

  9. Codeforces Round #436 (Div. 2) E. Fire

    http://codeforces.com/contest/864/problem/E 题意: 有一堆物品,每个物品有3个属性,需要的时间,失效的时间(一开始)和价值.只能一件一件的选择物品(即在选择 ...

随机推荐

  1. android.widget.TextView.setText() on a null object reference

    错误描述 java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView. ...

  2. training set, validation set, test set的区别

    training set: 用来训练模型 validation set : 用来做model selection test set : 用来评估所选出来的model的实际性能 我们知道,在做模型训练之 ...

  3. 实验1:Mininet源码安装和可视化拓扑工具

    一.实验目的 掌握 Mininet 的源码安装方法和 miniedit 可视化拓扑生成工具. 二.实验任务 使用源码安装 Mininet 的 2.3.0d6 版本,并使用可视化拓扑工具生成一个最简拓扑 ...

  4. 063 01 Android 零基础入门 01 Java基础语法 08 Java方法 01 无参无返回值方法

    063 01 Android 零基础入门 01 Java基础语法 08 Java方法 01 无参无返回值方法 本文知识点:无参无返回值方法 无参无返回值方法 案例 为什么使用方法?--方便复杂问题调用 ...

  5. 用集装箱装ASP。带有Docker和Azure Kubernetes服务的NET Core应用程序

    介绍 曾经有一个单一软件应用程序的时代,整个应用程序被打包并部署在作为单个进程运行的单个服务器上.我们都知道,在这个模型中,单点故障可能会导致整个应用程序崩溃. 微服务体系结构的发展是为了解决单片应用 ...

  6. 用Python爬取B站、腾讯视频、爱奇艺和芒果TV视频弹幕!

    众所周知,弹幕,即在网络上观看视频时弹出的评论性字幕.不知道大家看视频的时候会不会点开弹幕,于我而言,弹幕是视频内容的良好补充,是一个组织良好的评论序列.通过分析弹幕,我们可以快速洞察广大观众对于视频 ...

  7. python中remove函数的坑

    摘要:对于python中的remove()函数,官方文档的解释是:Remove first occurrence of value.大意也就是移除列表中等于指定值的第一个匹配的元素. 常见用法: a ...

  8. C# 生成chart图表的三种方式

    .net中,微软给我们提供了画图类(system.drawing.imaging),在该类中画图的基本功能都有.比如:直线.折线.矩形.多边形.椭圆形.扇形.曲线等等,因此一般的图形都可以直接通过代码 ...

  9. 蒲公英 · JELLY技术周刊 Vol.25 · Webpack 5 正式发布,你学废了么

    蒲公英 · JELLY技术周刊 Vol.25 阔别两年,Webpack 5 正式发布了,不仅清理掉很多冗余的功能,同样也为我们带来了很多新鲜的能力,不论是默认开启的持久缓存,还是反病毒保护,亦或者被其 ...

  10. MeteoInfoLab脚本示例:OMI Swath HDF数据

    这个例子读取OMI卫星Swath数据中的CloudFaction变量并绘图.脚本程序: #Add data file folder = 'D:/Temp/hdf/' fns = 'OMI-Aura_L ...