蓝桥杯 带分数



带分数

    100 可以表示为带分数的形式:100 = 3 + 69258 / 714

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

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

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

题目要求:
从标准输入读入一个正整数N (N<1000*1000)
程序输出该数字用数码1~9不重复不遗漏地组成带分数表示的全部种数。
注意:不要求输出每个表示,只统计有多少表示法!


例如:
用户输入:
100
程序输出:
11

再例如:
用户输入:
105
程序输出:
6


拿到这个题我的肝觉就是排列:

把这个1-9 个数全排列 然后不择手段的将其解剖组合。。。就是在中间插上个“+” 和“/” 

我到排列我就高兴。。最近刚学了一种功夫。。专杀排列:

下面来说一下 next_permutation(数组地址,数组地址加长度)。。这个你也不用查了 我给你举个例子你就明白了。。

一看就懂 

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
	int a[4]={1,2,3,4};
	do{
		cout<<a[1]<<" "<<a[2]<<" "<<a[3]<<endl;
	}while(next_permutation(a,a+4));
}

别忘了头文件 在算法<algorithm>里面

下面是结果 :

3 4 2
4 2 3
4 3 2
1 3 4
1 4 3
3 1 4
3 4 1
4 1 3
4 3 1
1 2 4
1 4 2
2 1 4
2 4 1
4 1 2
4 2 1
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

用这个东西处理排列问题最快乐 。

就是这个feel 倍爽儿!


下面我们说一下这个题吧!

反正排列已经好了 关键现在要处理这个数组的问题 处理数组就是要组合成三个数 x1+x2/x3=n;

 先说一下我要从数组中截取某一段数比如从a[0]-a[3]这样的数;

int f(int star,int end,int a[])
{
	if(star>end)
	return 1;
	int n=0;
	for(int i=star;i<=end;i++)
	{
		n=n*10+a[i];
	}
	return n;
}

这个也不用多说吧!

下面就是是如何选择截取了 :

我是这样选的 从头开始 x1 先是一位的整数然受是两位的。。。用一个最外层的for实现

然后是x2 我是因为x2要比x3大所以要比x3 的位数多至少一样多,这是我从某位高人那偷学的。。。

看看我的代码:

for(int i=0;i<=size;i++)
		{
			for(int j=8-(8-i)/2;j<8;j++)
			{
				int x1=f(0,i,a);
				int x2=f(i+1,j,a);
				int x3=f(j+1,8,a);
				if(x==x1+x2/x3&&x2==x3*(x2/x3))
				{
					cout<<x1<<"+"<<x2<<"/"<<x3<<endl;
				}
			}
		}
对就是这样 。。 中间的for的j是x2的最后一位 开始时j=8-(8-i)/2 是因为我要让x2比x3大 所以就不需要从i+1开始逐个递增了 这样省去了很多。。x2==x3*(x2/x3)这是判断x2/x3是不是整数;

好了到这就基本结束了!

对了上面的size是输入的n的位数 ,如果x1就超过了 后面就没必要加了

#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
int f(int star,int end,int a[])
{
	if(star>end)
	return 1;
	int n=0;
	for(int i=star;i<=end;i++)
	{
		n=n*10+a[i];
	}
	return n;
}
int main()
{
	int n;
	cin>>n;
	int size=0;
	int x=n;
	while(n)
	{
		size++;
		n=n/10;
	}
	int a[9]={1,2,3,4,5,6,7,8,9};
	do{
		for(int i=0;i<=size;i++)
		{
			for(int j=8-(8-i)/2;j<8;j++)
			{
				int x1=f(0,i,a);
				int x2=f(i+1,j,a);
				int x3=f(j+1,8,a);
				if(x==x1+x2/x3&&x2==x3*(x2/x3))
				{
					cout<<x1<<"+"<<x2<<"/"<<x3<<endl;
				}
			}
		}
	}while(next_permutation(a,a+9));
}

好了 , 每次都要感谢自己继续着,希望能够帮到你们,有错误大家指正


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值