其他分享
首页 > 其他分享> > 跳跳棋「LCA+二分答案」

跳跳棋「LCA+二分答案」

作者:互联网

跳跳棋「LCA+二分答案」

题目描述

跳跳棋是在一条数轴上进行的。棋子只能摆在整点上。每个点不能摆超过一个棋子。

我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在\(a,b,c\)这三个位置。我们要通过最少的跳动把他们的位置移动成\(x,y,z\)。(棋子是没有区别的)

跳动的规则很简单,任意选一颗棋子,对一颗中轴棋子跳动。跳动后两颗棋子距离不变。一次只允许跳过\(1\)颗棋子。

写一个程序,首先判断是否可以完成任务。如果可以,输出最少需要的跳动次数。

输入格式

第一行包含三个整数,表示当前棋子的位置\(a\) \(b\) \(c\)。(互不相同)

第二行包含三个整数,表示目标位置\(x\) \(y\) \(z\)。(互不相同)

输出格式

如果无解,输出一行\(NO\)。

如果可以到达,第一行输出\(YES\),第二行输出最少步数。

输入输出样例

输入 #1

1 2 3
0 3 5

输出 #1

YES
2

说明/提示

\(20%\) 输入整数的绝对值均不超过\(10\)

\(40%\) 输入整数的绝对值均不超过\(10000\)

\(100%\) 绝对值不超过\(10^{9}\)


思路分析

声明:本蒟蒻喜欢把东西讲的很详细(因为我不会),所以篇幅有点长

此题神级建模!
——老姚

没有思路

神级建模,暗示看不出来

清华集训,暗示本蒟蒻不配

这题是真滴没想到能扯到\(LCA\)果断一个特判一个NO骗分就走


细节见代码

Code

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
inline int read(){
	int x = 0,f = 1;
	char ch = getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x = (x<<1)+(x<<3)+(ch^48);ch = getchar();}
	return x*f;
}
const int inf = 0x3f3f3f3f;
struct Node{
	int x,y,z;
	void Init(){
		x = read(),y = read(),z = read();
		if(x>y)swap(x,y); //记得维护顺序
		if(x>z)swap(x,z);
		if(y>z)swap(y,z);
	}
}a,b,ra,rb;
bool check(Node u,Node v){ //判断终极状态相同与否
	return u.x==v.x&&u.y==v.y&&u.z==v.z;
}
int step,k;
Node getroot(Node t,int s){ //转移到终极状态
	for(step=0;s;step+=k){
		int d1 = t.y-t.x,d2 = t.z-t.y;
		if(d1==d2)return t;
		if(d1<d2){
			k = min((d2-1)/d1,s); //跳多些
			t.x+=k*d1,t.y+=k*d1;
			s-=k;
		}
		else{
			k = min((d1-1)/d2,s);
			t.z -= k*d2,t.y-=k*d2;
			s-=k;
		}
	}
	return t;
}
int main(){
	a.Init(),b.Init();
	ra = getroot(a,inf);
	int step1 = step;
	rb = getroot(b,inf);
	int step2 = step;
	if(!check(ra,rb)){ //不同
		printf("NO\n");
		return 0;
	}
	if(step1<step2){ //一般求LCA的思想,先让远的先跳
		swap(a,b);
		swap(step1,step2);	
	}
	a = getroot(a,step1-step2);//跳到相同位置再一起跳
	int l = 0,r = step2;
	while(l<r){
		int mid = (l+r)>>1; //枚举到祖先的距离,一起跳
		if(check(getroot(a,mid),getroot(b,mid)))r = mid;
		else l = mid+1;
	}
	printf("YES\n%d\n",(l<<1)+step1-step2);//记得×2和加上a先跳的
}									

标签:二分,状态,ch,int,跳动,跳棋,棋子,LCA,终极
来源: https://www.cnblogs.com/hhhhalo/p/13374482.html