Problem:Unit Fraction Partition

Problem:Unit Fraction Partition

这是一道非常经典的题目,可能会常出现在考试中,具体如下:
Description
给出数字P,Q,A,N,代表将分数P/Q分解成至多N个分数之和,这些分数的分子全为1,且分母的乘积不超过A。例如当输入数据为2 3 120 3时,我们可以得到以下几种分法:
3/2=1/3+1/3
=1/2+1/6
=1/4+1/4+1/6
=1/3+1/6+1/6
Input
本题含有多组测试数据,每组给出四个数P,Q,A,N,其中 p,q <= 800, A <= 12000,N <= 7.当输入的四个数均为0时,代表测试结束.
Output
针对每组数据,输出共有多少种不同的分法。

Sample Input
2 3 120 3
2 3 300 3
2 3 299 3
2 3 12 3
2 3 12000 7
54 795 12000 7
2 3 300 1
2 1 200 5
2 4 54 2
0 0 0 0

Sample Output
4
7
6
2
42
1
0
9
3

|这道题的具体解法是找到每个值的关系,判断它的范围,
然后进行约分后,如果符合,就计数。
代码如下:

#include<bits/stdc++.h>//可爱的头文件
using namespace std;
int tot,vis[10086];//计数和最后输出用的
int p,q,a,n;//题目要求
int cmp(int p1,int q1,int p2,int q2) 
{
	return p1*q2-q1*p2;
}
void sub(int &p1,int &q1,int p2,int q2) 
{
	p1=p1*q2-p2*q1;
	q1=q1*q2;
}
void dfs(int zm,int zd,int pre,int dep,int sum)
 {
	int xm,xd;
    if(sum==n+1&&zm!=0) return;//分支限界搜索
	if(sum<=n+1&&zm==0) 
	{
		tot++;//满足要求,计数
		return;
	}
	for(int d=pre;d<=dep;d++) 
	{
		if(cmp(zm,zd,1,d) < 0) continue;
		sub(xm = zm,xd=zd,1,d);
		if(cmp(xm,xd,n - sum,d)>0) break;
		dfs(xm,xd,d,dep/d,sum+1);//继续往下搜
	}
}
int main() 
{
	int i=1;
	while(cin>>p>>q>>a>>n,p!=0) //无限输入,为0保证
	//了除数不为0,且满足全为0退出
	{
		tot=0;
		dfs(p,q,1,a,1);
		vis[i]=tot;//存起来一起输出
		i++;
	}
	for(int j=1;j<i;j++)
	   cout<<vis[j]<<endl;//输出
}

总之来说,这道题应该是偏基础,应该很简单,好好理解吧
大家都懂:

#include<bits/stdc++.h>
using namespace std;
int tot,vis[10086];
int p,q,a,n;
int cmp(int p1,int q1,int p2,int q2) 
{
	return p1*q2-q1*p2;
}
void sub(int &p1,int &q1,int p2,int q2) 
{
	p1=p1*q2-p2*q1;
	q1=q1*q2;
}
void dfs(int zm,int zd,int pre,int dep,int sum)
 {
	int xm,xd;
	if(sum==n+1&&zm!=0) return;
	if(sum<=n+1&&zm==0) 
	{
		tot++;
		return;
	}
	for(int d=pre;d<=dep;d++) 
	{
		if(cmp(zm,zd,1,d) < 0) continue;
		sub(xm = zm,xd=zd,1,d);
		if(cmp(xm,xd,n - sum,d)>0) break;
		dfs(xm,xd,d,dep/d,sum+1);
	}
}
int main() 
{
	int i=1;
	while(cin>>p>>q>>a>>n,p!=0) 
	{
		tot=0;
		dfs(p,q,1,a,1);
		vis[i]=tot;
		i++;
	}
	for(int j=1;j<i;j++)
	   cout<<vis[j]<<endl;
}

加油,少抄代码。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值