题解 P4264 【[USACO18FEB]Teleportation S】
安利一下自己博客园博客:传送门
题解
先吐槽一波题目:便便传送门,出题人还真的有一点厉害的滑稽。
废话不多说。
首先问题的本质就是求如果当这个传送门的端点位于
因为这个
因为有
以上的算法比较的简单,但是我们需要用数学计算出每一个交接点的位置就是
其中
对于交接点,每一个函数对最终的答案都是有贡献的,例如如果
对于图片中另外一种情况,如果
可以选择用
ac代码
# include <cstdio>
# include <cstring>
# include <algorithm>
# include <ctype.h>
# include <iostream>
# include <cmath>
# include <map>
# define LL long long
# define ms(a,b) memset(a,b,sizeof(a))
# define ri (register int)
# define inf (0x7f7f7f7f)
# define pb push_back
# define fi first
# define se second
# define pii pair<int,int>
using namespace std;
inline int gi(){
int w=0,x=0;char ch=0;
while(!isdigit(ch)) w|=ch=='-',ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return w?-x:x;
}
int n;
map<int,int>mp;
LL x=0,y=-inf,s=0;
int main(){
n=gi();
for (int i=1;i<=n;i++){
int a=gi(),b=gi();
x+=abs(a-b);
if (abs(a)>abs(a-b)) continue;
mp[b]+=2;
if ((a<b&&a<0)||(a>=b&&a>=0)) mp[0]--,mp[2*b]--;
if ((a<b&&a>=0)||(a>=b&&a<0)) mp[2*b-2*a]--,mp[2*a]--;
}
LL ans=x;
map<int,int>::iterator it;
for (it=mp.begin();it!=mp.end();it++){
int ny=it->fi,tmp=it->se;
x+=s*(ny-y); y=ny; s+=tmp;
ans=min(ans,x);
}
printf("%lld\n",ans);
return 0;
}