【小水题】2024.3.31

2024.3.31 【人间骄阳刚好,风吹过树梢,彼时他们正当年少——某某】

Sunday 二月二十二


<BGM = 那年·年少 - 宋宇宁>
<theme = oi-“search”>
来看道典题

P1763 埃及分数

附本体链接

//2024.3.31
//by white_ice
#include<bits/stdc++.h>
using namespace std;
#define itn long long
#define int long long
const int oo = 10000007;

int jgby(int a,int b){while(b^=a^=b^=a%=b);return a;}
int ngm (itn a,itn b){return a<b?a:b;}
itn jntm(itn a,itn b){return a>b?a:b;}

int a,b,madis;
int out[oo],st[oo];
int s;

bool dfs(itn a,itn b,int dis){
	if (dis == madis){
		if (a==1&&b>st[dis-1]&&(b<out[dis]||!out[dis])){
			st[dis] = b;
			memcpy(out,st,sizeof(st));
			return true;
		}
		return false;
	}
	if (dis == madis - 1){
		for (itn z=(b<<2)/a/a+1;z<ngm((s<<1)/a,s*s/a);z++){
			itn d = a*a*z*z-(b<<2)*z;
            itn s = sqrt(d);
			if (s*s!=d||a*z+s&1)
				continue;
			st[dis] = a*z-s>>1;
            st[dis+1]=a*z+s>>1;
			if (st[dis+1]<out[dis+1]||!out[dis+1]){
				memcpy(out,st,sizeof(st));
				return true;
			}
		}
		return false;
	}

	itn l = jntm(st[dis-1],(b-1)/a)+1LL;
    int r = (madis-dis+1)*b/a;

	bool flag = 0;
	for (int i=l;i<r;i++){
		itn tx = a*i-b,ty = b*i;
        itn g = jgby(tx, ty);
		st[dis] = i;

		if (dfs(tx/g,ty/g,dis+1))
			flag = 1;
	}
	return flag;
}

signed main (){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);

    cin >> a >> b;

    bool tag = 0;
    while (!tag){
        s = 100;
        madis++;
        while (s<1e7&&!tag)
            s = (s<<3)+(s<<1),tag = dfs(a,b,1);
    }

    for (itn i=1;i<=madis;i++)
        cout << out[i] << ' ';

    return 0;
}

本题使用了iddfs,也就是迭代加深搜索。

通过每次设定一个预期的dis,也就是预定深度,再依据此深度为限制进行搜索。
本代码中设为madis。

当搜索致dis = madis - 1时,若剩余分数仍久分子不为一,则剪枝优化掉。

下面推一下柿子:
$$
\frac{a}{b} = \frac{1}{x}\ + \ \frac{1}{y}\

\left{
\begin{aligned}
az = x+y\
bz = xy
\end{aligned}
\right.
\rArr
x^2\ - \ azx\ - \ bz \ =\ 0
$$

也就是:
x   =   a z   −   Δ 2 y   =   a z   +   Δ 2 x\ = \ \frac{az\ - \ \sqrt{\Delta}}{2}\\ y\ = \ \frac{az\ + \ \sqrt{\Delta}}{2} x = 2az  Δ y = 2az + Δ
柿子非常好看啊。

只要证明一下$ \Delta $能够被整开就行。

然后就代码就行。

  • 30
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值