首页 > 其他分享 >ABC273F Hammer 题解

ABC273F Hammer 题解

时间:2024-07-27 14:31:34浏览次数:10  
标签:堵墙 ABC273F int 题解 read while Hammer

ABC273F Hammer 题解

题目大意

数轴上有 \(n\) 个锤子和 \(n\) 堵墙,第 \(i\) 个锤子位于 \(x_i\),第 \(i\) 堵墙位于 \(y_i\),第 \(i\) 个锤子可以对应的敲开第 \(i\) 堵墙。以原点为起点,给定终点 \(t\),问最少移动多少个单位长度才能走到 \(t\)。必须拿到对应锤子敲开墙才能走过这堵墙。

Solve

考虑建图。对于一堵墙 \(y_i\),对于所有必须先经过这堵墙才能到达的点 \(u\),我们连一条从 \(y_i\) 到 \(u\) 的有向边,意为限制必须先经过 \(y_i\) 才能到 \(u\)。然后再连一条从 \(x_i\) 到 \(y_i\) 的有向边,意义同上。处理完之后再从原点向所有点连有向边。

先离散化,再在建出来的图上跑拓扑最长路即可,每条边的边权即为两端点位置之差。

至于为什么是最长路,由于图是在一个数轴上建出来的,比较特殊,所以一个点若受到多个点的约束,那么约束它的点之间一定也有约束关系,不会相互独立,所以更长的路一定包含更短的路的状态。意会一下。

无解的情况显然是从 \(s\) 到 \(t\) 的路径上有环,即约束 \(t\) 的条件无法全被满足,拓排完判断一下 \(t\) 的入度是否被消到 \(0\) 即可。

Code

#include<bits/stdc++.h>
using namespace std;
inline int read()
{
	short f=1;
	int x=0;
	char c=getchar();
	while(c<'0'||c>'9')	{if(c=='-')	f=-1;c=getchar();}
	while(c>='0'&&c<='9')	x=(x<<1)+(x<<3)+(c^48),c=getchar();
	return x*f;
}
const int N=1510,M=3010;
int n,s,t,x[N],y[N],k[M],ind[M],m;
long long f[M];
vector<int>e[M];
inline void topo()
{
	queue<int>q;q.push(s);
	while(!q.empty())
	{
		int u=q.front();q.pop();
		if(u==t)    break;
		for(int i:e[u])
		{
			f[i]=max(f[i],f[u]+abs(k[i]-k[u]));
			if(!--ind[i])	q.push(i);
		}
	}
	if(ind[t])	puts("-1");
	else	printf("%lld",f[t]);
}
signed main()
{
	n=read();t=read();m=(n<<1);
	for(int i=1;i<=n;i=-~i)	k[i]=x[i]=read();
	for(int i=1;i<=n;i=-~i)	k[i+n]=y[i]=read();
	k[m+1]=0;k[m+2]=t;
	sort(k+1,k+m+3);
	m=unique(k+1,k+m+3)-k-1;
	for(int i=1;i<=n;i=-~i)
		x[i]=lower_bound(k+1,k+m+1,x[i])-k,
		y[i]=lower_bound(k+1,k+m+1,y[i])-k;
	t=lower_bound(k+1,k+m+1,t)-k;
	s=lower_bound(k+1,k+m+1,0)-k;
	for(int i=1;i<=n;i=-~i)
	{
		e[y[i]].push_back(x[i]);ind[x[i]]=-~ind[x[i]];
		if(x[i]>s)
			for(int j=x[i]+1;j<=m;j=-~j)
				e[x[i]].push_back(j),ind[j]=-~ind[j];
		else
			for(int j=1;j<x[i];j=-~j)
				e[x[i]].push_back(j),ind[j]=-~ind[j];
	}
	for(int i=1;i<=m;i=-~i)
		if(i!=s)	e[s].push_back(i),ind[i]=-~ind[i];
	return topo(),0;
}

标签:堵墙,ABC273F,int,题解,read,while,Hammer
From: https://www.cnblogs.com/sorato/p/18326905

相关文章

  • Codeforces Round 962 (Div. 3) 题解
    A.Legshttps://codeforces.com/contest/1996/problem/A翻译:农夫约翰的农场又迎来了美好的一天。农夫约翰来到农场后,数了数n条腿。众所周知,农场里只住着鸡和牛,一只鸡有2条腿,而一头牛有4条腿。假设约翰农场主数清了所有动物的腿,那么他的农场里最少有多少动物?思路求最少......
  • stata 代码实现熵值法计算 含常见问题解答
    适用:面板数据均可stata版本:无要求例如,使用了一个10年的省级面板数据,含15个指标,现在来计算各地区的熵值法得分。其中,x1x2x3x4x6x7x8x9x11x12x13x14x15是正向指标;而x5x10是负向指标。1.定义面板,定义指标的正负。tssetidyearglobalxlist1"x1x2x3x4x6x......
  • CF585F Digits of Number Pi 题解
    Description给定长度为\(n\)的数字串\(s\)和长度为\(d\)的不含前导零的数字串\(x,y(x\ley)\)。求存在长度至少为\(\left\lfloor\frac{d}{2}\right\rfloor\)的子串是\(s\)的子串的数字串\(t\in[x,y]\)的数量。\(n\le10^3\),\(d\le50\),答案对\(10^9+7\)取......
  • CF578E Walking! 题解
    Description给定一个长度为\(n\)的只包含L,R的字符串\(s\)。构造一个\(n\)排列\(p\)满足\(s[p_i]\nes[p_{i+1}](1\lei<n)\)。最小化\(p\)中\(p_i>p_{i+1}(1\lei<n)\)的数量。\(n\le10^5\),数据保证有解。Solution考虑把\(p\)中的每个极长连......
  • 小信小友逛庙会 题解
    题目id:9774题目描述小信与小友相约逛庙会。但是庙会人很多,他们走散了。庙会能表示成\(n×m\)的矩阵,小信在'\(C\)',小友在'\(D\)','\(.\)'表示能走,'#'表示店铺(也就是不能走)。每分钟,小信可以往\(8\)个方向移动一格,而小友可以移动一次或者两次,每次可以往\(4\)个方向(上下左右)移动一......
  • 开心消消乐 题解
    题目id:8578题目描述\(A\)酱最近在玩开心消消乐,由于是异次元的游戏,所以规则可能和地球上的有所不同。开心消消乐是一个在大圆环上进行的游戏,环上有若干个宝石,每颗宝石都有自己的积分,由于消消乐是一个三消游戏,我们每次可以挑选其中一个宝石消去,消去宝石的积分为他的积分和左右相......
  • CF1988F 较草题解
    \[\begin{aligned}&f_{i,j,k},g_{i,j,k}\to(i\text{permutation},j\text{premaxorsufmax},k(a[l]>a[l-1]))\\&\text{Initialize:}f_{1,1,0}=g_{1,1,0}=1\\&\text{Transferforf,g}\\&f_{i,j,k}=f_{i-1,j-1,k-1......
  • 参天大树 题解
    题目id:5602题目描述丛林中矗立着一棵参天大树,高度为\(y\)。大树\(2\simp\)高度处,每个位置都有一只蚱蜢。一只蚱蜢如果在\(x\)高度处,那么它可以跳到\(2x、3x、4x、......\)等任意一个\(x\)的倍数处。你想在\(2\simy\)高度范围内,找到一个尽可能高且不会有任何蚂蚱能跳到的位......
  • 力扣题解1-两数之和
    LeetCode第一题"两数之和"(TwoSum)问题分析过程:这个问题可以通过多种方法解决,包括暴力解法和使用哈希表的解法。以下是详细的分析过程:暴力解法:遍历数组中的每一对元素,检查它们的和是否等于目标值。时间复杂度是O(n^2),其中n是数组的长度。使用哈希表:使用一......
  • Pag动画:umi+libpag+copy-webpack-plugin实现及问题解决
    1、package.json添加如下,安装依赖:"libpag":"^4.2.84","copy-webpack-plugin":"9.1.0",为什么是写死的旧版本,后面解释2、使用的方法,这里只是一个小示例,具体如何使用看个人(这里主要是想记录过程中出现的问题及解决方式): constinit=async()=>{   constPag......