HDU 3830 Checkers

题意:

有三个棋子  可以隔一个棋子跳  不能隔两个跳  问状态u到状态v最少跳几步

思路:

对于一个状态三个棋子的位置可以设为 x y z  (小到大)

只有当y-x=z-y的时候  跳的方法为两种  即  y跳过x  或  y跳过z

在上式等式不成立时  短的一边可以跳许多次  直到大小关系改变

那么这样就形成了二叉树的结构  我们将y向左右跳的状态分别作为原状态的儿子  将两边其中一个向中间跳的状态作为原状态的父亲

那么这时u和v的可达性就变成了  他们是不是同一个根  于是我们可以从u和v跳到头  判断一下

如果能跳  要跳几次呢??  这时利用LCA  方法与倍增法相同  即  u和v先爬到同一高度  再同时爬

爬的方法和刚才的状态向根移动相同  由于没有倍增打表  因此同一深度后我们要用二分法确定爬的高度

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<cstdlib>
#include<ctime>
#include<cmath>
using namespace std;
typedef unsigned long long LL;
#define M 1100
#define N 16

struct state {
	int x[3];
	void Sort() {
		sort(x, x + 3);
	}
	int Root() {
		int floor = 0;
		int a1 = x[1] - x[0], a2 = x[2] - x[1];
		while (a1 != a2) {
			if (a1 > a2) {
				int d = (a1 - 1) / a2;
				floor += d;
				x[2] -= d * a2;
				x[1] -= d * a2;
			} else {
				int d = (a2 - 1) / a1;
				floor += d;
				x[0] += d * a1;
				x[1] += d * a1;
			}
			Sort();
			a1 = x[1] - x[0], a2 = x[2] - x[1];
		}
		return floor;
	}
	bool operator==(const state ff) const {
		return (x[0] == ff.x[0]) && (x[1] == ff.x[1]) && (x[2] == ff.x[2]);
	}
	void GoUp(int floor) {
		while (floor) {
			int a1 = x[1] - x[0], a2 = x[2] - x[1];
			if (a1 > a2) {
				int d = (a1 - 1) / a2;
				if (d > floor)
					d = floor;
				floor -= d;
				x[2] -= d * a2;
				x[1] -= d * a2;
			} else {
				int d = (a2 - 1) / a1;
				if (d > floor)
					d = floor;
				floor -= d;
				x[0] += d * a1;
				x[1] += d * a1;
			}
			Sort();
		}
	}
} u, v, fau, fav;

int main() {
	int fu, fv, ans;
	while (~scanf("%d%d%d%d%d%d", &u.x[0], &u.x[1], &u.x[2], &v.x[0], &v.x[1],
			&v.x[2])) {
		u.Sort();
		v.Sort();
		fau = u;
		fav = v;
		fu = fau.Root();
		fv = fav.Root();
		if (fau == fav) {
			puts("YES");
			if (fu > fv) {
				ans = fu - fv;
				u.GoUp(ans);
			} else if (fv > fu) {
				ans = fv - fu;
				v.GoUp(ans);
			} else
				ans = 0;
			int l = 0, r = min(fu, fv), mid, tmp;
			while (l <= r) {
				mid = (l + r) >> 1;
				fau = u;
				fav = v;
				fau.GoUp(mid);
				fav.GoUp(mid);
				if (fau == fav) {
					r = mid - 1;
					tmp = mid;
				} else
					l = mid + 1;
			}
			printf("%d\n", ans + (tmp << 1));
		} else
			puts("NO");
	}
	return 0;
}
时间: 2024-12-01 08:21:01

HDU 3830 Checkers的相关文章

[hdu 3830] checker

题意 在一维空间内玩三个跳棋. 给定三个跳棋初始点的坐标 $a, b, c$ , 问它们能不能跳到结束点 $x, y, z$ . 如果能, 还要求出最少跳多少次. $- {10} ^ 9 \le a, b, c, x, y, z \le {10} ^ 9$ . 分析 实现 #include <cstdio> #include <cstring> #include <cstdlib> #include <cctype> #include <algorit

图论 500题——主要为hdu/poj/zoj

转自——http://blog.csdn.net/qwe20060514/article/details/8112550 =============================以下是最小生成树+并查集======================================[HDU]1213   How Many Tables   基础并查集★1272   小希的迷宫   基础并查集★1325&&poj1308  Is It A Tree?   基础并查集★1856   More i

hdu图论题目分类

=============================以下是最小生成树+并查集====================================== [HDU] 1213 How Many Tables 基础并查集★ 1272 小希的迷宫 基础并查集★ 1325&&poj1308 Is It A Tree? 基础并查集★ 1856 More is better 基础并查集★ 1102 Constructing Roads 基础最小生成树★ 1232 畅通工程 基础并查集★ 123

题单二:图论500

http://wenku.baidu.com/link?url=gETLFsWcgddEDRZ334EJOS7qCTab94qw5cor8Es0LINVaGMSgc9nIV-utRIDh--2UwRLvsvJ5tXFjbdpzbjygEdpGehim1i5BfzYgYWxJmu ==========  以下是最小生成树+并查集=========================[HDU]1213         How Many Tables        基础并查集★1272         小

图论五百题!

生死看淡不服就淦,这才是人生! =============================以下是最小生成树+并查集======================================[HDU]1213 How Many Tables 基础并查集★1272 小希的迷宫 基础并查集★1325&&poj1308 Is It A Tree? 基础并查集★1856 More is better 基础并查集★1102 Constructing Roads 基础最小生成树★1232 畅通工程 基

图论精炼500题

忘了从哪转的了... =============================以下是最小生成树+并查集====================================== [HDU] 1213               How Many Tables                    基础并查集★ 1272               小希的迷宫                     基础并查集★ 1325&&poj1308    Is It A Tree?       

学习 LCA&amp;&amp;RMQ

参考:点击打开链接 点击打开链接      点击打开链接(一些总结) 点击打开链接(不错的模板) 题目:点击打开链接 花了4天时间做完了这个专题,LCA的问题用处还是很大,同时能体会RMQ的ST算法中dp的味道.基本方法就是ST,LCA转RMQ,LCA的Tarjan,LCA倍增(这个可存储边权) 这个专题后面四道题都非常好,推荐大家做做. 细节: 1. ST方法2^i 包含自己,因此其真实只包含到i+2^k-1的范围. 2. Tarjan一般都很快,但不适合修改类型的问题,关于权值长度之类的,S

图论500题

=============================以下是最小生成树+并查集====================================== [HDU] 1213   How Many Tables   基础并查集★ 1272   小希的迷宫   基础并查集★ 1325&&poj1308  Is It A Tree?   基础并查集★ 1856   More is better   基础并查集★ 1102   Constructing Roads  基础最小生成树★ 12

LCA&amp;&amp;RMQ问题

参考:点击打开链接 点击打开链接      点击打开链接(一些总结) 点击打开链接(不错的模板) 题目:点击打开链接 花了4天时间做完了这个专题,LCA的问题用处还是很大,同时能体会RMQ的ST算法中dp的味道.基本方法就是ST,LCA转RMQ,LCA的Tarjan,LCA倍增(这个可存储边权) 这个专题后面四道题都非常好,推荐大家做做. 细节: 1. ST方法2^i 包含自己,因此其真实只包含到i+2^k-1的范围. 2. Tarjan一般都很快,但不适合修改类型的问题,关于权值长度之类的,S