P1852 跳跳棋(建模&LCA)
Posted Harris-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1852 跳跳棋(建模&LCA)相关的知识,希望对你有一定的参考价值。
P1852 跳跳棋(建模&LCA)
往外跳有个两个状态,往里跳只能有一个唯一父亲状态。
所以是一个二叉树。
将给定的起始和目标状态 向上找到根,判断是否相等。不相等无解。
否则类似求LCA的思想二分步数即可。
// Problem: P1852 跳跳棋
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1852
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// Date: 2021-07-30 09:43:38
// --------by Herio--------
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define ios ios::sync_with_stdio(false),cin.tie(0)
void Print(int *a,int n){
for(int i=1;i<n;i++)
printf("%d ",a[i]);
printf("%d\\n",a[n]);
}
struct node{
int a[3];
bool operator != (node b)const{
for(int i=0;i<3;i++) if(a[i]!=b.a[i]) return true;
return false;
}
}A,B;
int tmp;
node fun(node A,int k){
int d1=A.a[1]-A.a[0],d2=A.a[2]-A.a[1];
if(d1==d2) return A;
else if(d1<d2){
int t=min(k,(d2-1)/d1);
k-=t;
tmp+=t;
A.a[0]+=t*d1,A.a[1]+=t*d1;
}
else {
int t=min(k,(d1-1)/d2);
k-=t;
tmp+=t;
A.a[1]-=t*d2,A.a[2]-=t*d2;
}
if(k) return fun(A,k);
else return A;
}
int main(){
for(int i=0;i<3;i++) scanf("%d",&A.a[i]);
for(int i=0;i<3;i++) scanf("%d",&B.a[i]);
sort(A.a,A.a+3);
sort(B.a,B.a+3);
int dep1=0,dep2=0;
node na=fun(A,inf);dep1=tmp,tmp=0;
node nb=fun(B,inf);dep2=tmp,tmp=0;
if(na!=nb) return puts("NO"),0;
if(dep1>dep2){
swap(dep1,dep2);
swap(A,B);
}
int ans=dep2-dep1;
B=fun(B,ans);
int l=0,r=dep1;
while(l<r){
int m=l+r>>1;
if(fun(A,m)!=fun(B,m)) l=m+1;
else r=m;
}
ans+=(l<<1);
puts("YES");
printf("%d\\n",ans);
return 0;
}
以上是关于P1852 跳跳棋(建模&LCA)的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ 2144 跳跳棋(神仙建模题,倍增 LCA,二分)BZOJ修复工程