历届试题 带分数

2019.2.18写

解题思路

首先感谢这些大神的博客,附上传送门:带分数https://blog.csdn.net/acmman/article/details/19282173

                                                        全排列https://blog.csdn.net/summerxiachen/article/details/60579623#commentBox

这题的解题方法是“全排列”+“剪枝”。先通过全排列得到1~9这九位数的每一次的变化,在每一次的变化中去判断是否满足题目要求的" num = a + b/c "。剪枝的过程是通过" num = a + b/c "和题意判断出 a<num ; b%c==0。注意的是:a从1~9中如果取用了n位,那么b一定只能从剩下的(9-n)中取用至少(9-n)/2位,最多(9-n)-1位,最后才是c取用的位数。


问题描述
100 可以表示为带分数的形式:100 = 3 + 69258 / 714。

还可以表示为:100 = 82 + 3546 / 197。

注意特征:带分数中,数字1~9分别出现且只出现一次(不包含0)。

类似这样的带分数,100 有 11 种表示法。

输入格式
从标准输入读入一个正整数N (N<1000*1000)

输出格式
程序输出该数字用数码1~9不重复不遗漏地组成带分数表示的全部种数。

注意:不要求输出每个表示,只统计有多少表示法!


样例输入1
100
样例输出1
11
样例输入2
105
样例输出2
6


附上代码

#include<iostream>
using namespace std;
int a[10]={0,1,2,3,4,5,6,7,8,9};
int num=0;
int ans=0;//统计总数 
int main()
{
	void AllParmutation(int,int);//全排列 
	void Found(int);//对每一次的排列进行筛选 
	int sum(int,int);//转换成相应的一个多位整数 
	cin>>num;
	AllParmutation(1,10);
	cout<<ans<<endl;
	return 0;
} 
int sum(int start,int end)
{
	int sum=0;
	for(int i=start;i<end;i++)
		sum=sum*10+a[i+1];
	return sum;
}
void Found(int n)
{	//位数从1~9之间选 
	for(int i=1;i<n;i++)
	{
		int a=sum(0,i);//确定a 
		if(a>=num)
			return;
		for(int j=i+(n-i)/2;j<n-1;j++)
		{
			int b=sum(i,j);//确定b 
			int c=sum(j,n-1);//确定c 
			if((b>c)&&(b%c==0)&&(num==a+b/c))
				ans++;
		}
	}
}
void AllParmutation(int start,int n)
{
	if(start==n)
	{
		Found(n);
	}
	for(int i=start;i<n;i++)
	{
		swap(a[start],a[i]);
		AllParmutation(start+1,n);
		swap(a[start],a[i]);
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值