AT3518 4/N

既然是埃及分数,考虑用这题的方法来解,可以去看对这题的题解

但是这两题还是有点不同的,我们可以考虑这题有一些题解,因为并没有要求分解出的 h,w,rh,w,r 不相同,所以我们考虑当 nn 是偶数时,2n=1n+1n+1n÷2\frac{2}{n} = \frac{1}{n} + \frac{1}{n} + \frac{1}{n \div 2},而用搜索其实会耗时很久。

代码改一下即可:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <utility>
#include <cmath>
#include <cstring>
using namespace std;

#define int unsigned long long

static char buf[1000000], * p1 = buf, * p2 = buf;
#define getchar() p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1000000, stdin), p1 == p2) ? EOF : *p1++

inline int read()
{
	register char ch = getchar();
	register int x = 0;
	while (ch < '0' || ch > '9') ch = getchar();
	while (ch >= '0' && ch <= '9')
	{
		x = (x << 1) + (x << 3) + (ch ^ 48);
		ch = getchar();
	}
	return x;
}

inline void write(int x)
{
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}

inline int gcd(register int a, register int b) // 计算最大公因数
{
	return (b == 0 ? a : gcd(b, a % b));
}

#define lcm(a, b) (a * b / gcd(a, b)) // 最小公倍数

inline pair<int, int> add(const pair<int, int>& a, const pair<int, int>& b) // a.first 表示第一个分数的分子,a.second 表示第一个分数的分母,b.first 表示第二个分数的分子,b.second 表示第二个分数的分母
{
	register int newfm = lcm(a.second, b.second);
	register int newfz = newfm / a.second * a.first + newfm / b.second * b.first;
	register int g = gcd(newfm, newfz);
	newfm /= g;
	newfz /= g;
	return make_pair(newfz, newfm);
}

inline pair<int, int> Minus(register const pair<int, int>& a, register const pair<int, int>& b)
{
	register int newfm = lcm(a.second, b.second);
	register int newfz = newfm / a.second * a.first - newfm / b.second * b.first;
	register int g = gcd(newfm, newfz);
	newfm /= g;
	newfz /= g;
	return make_pair(newfz, newfm);
}

inline bool bigger(register const pair<int, int>& a, register const pair<int, int>& b) // 返回第一个分数 >= 第二个分数
{
	register int newfm = lcm(a.second, b.second);
	register int nfz1 = newfm / a.second * a.first;
	register int nfz2 = newfm / b.second * b.first;
	return nfz1 >= nfz2;
}

inline bool big(register const pair<int, int>& a, register const pair<int, int>& b) // 返回第一个分数 >= 第二个分数
{
	register int newfm = lcm(a.second, b.second);
	register int nfz1 = newfm / a.second * a.first;
	register int nfz2 = newfm / b.second * b.first;
	return nfz1 > nfz2;
}

const int N = 1e5 + 5;

int a, b, tdep;
pair<int, int> k;
int arr[N], res[N];

inline void dfs(register int dep, register pair<int, int> p)
{
	if (dep == tdep)
	{
		register pair<int, int> q = Minus(k, p);
		if (q.first != 1) return;
		arr[dep] = q.second;
		for (register int i = 1; i <= tdep; ++i) printf("%llu ", arr[i]);
		puts("");
		exit(0);
		return;
	}
	register pair<int, int> t = Minus(make_pair(a, b), make_pair(p.first, p.second));
	register int minn = max((int)arr[dep - 1], (int)ceil(t.second * 1.0 / t.first));
	register int l = tdep - dep + 1;
	for (register int i = minn; big(add(p, make_pair(l, i)), k); ++i)
	{
		arr[dep] = i;
		dfs(dep + 1, add(p, make_pair(1, i)));
	}
}

signed main()
{
	a = 4, b = read();
	k.first = a;
	k.second = b;
	if (b == 2)
	{
		printf("1 2 2\n");
		return 0;
	}
	else if (b % 2 == 0)
	{
		printf("%llu %llu %llu\n", b, b, b >> 1llu);
		return 0;
	}
	register int tmp = gcd(a, b);
	a /= tmp;
	b /= tmp;
	register int i, j;
	memset(res, 0, sizeof(res));
	tdep = 3;
	dfs(1, make_pair(0, 1));
	return 0;
}
posted @   HappyBobb  阅读(3)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示