蓝桥杯试题 历届试题 带分数
问题描述
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
粗略分析:
这个题目的思路是将1~9进行一个全排列,再将‘+’和‘\’插入其中,再判断该式带入演算是否成立,若成立,则count自加一。
细致分析:
例:
_1_2_3_4_5_6_7_8_9,将‘+’和‘\’插入在下划线中,由于输入的数据N<1000*1000,所以,‘+’能够插入的范围就在第2个下划线到第6个下划线之间(包括该两点),而’/'前面的数字个数一定是大于等于后面的数字个数,不然,后面相除的结果为0!
而这时我们在想,其实就是将一个数字串像切割一样,切成三段,只不过第一刀需要切在第一个和第六个之间,再将字符串转化为数字,满足一个算式,则成立。
到这里,我们就需要解决以下问题:
- 全排列
- 将部分字符串转化为数字
对于问题的解决
- 全排列可以由C++algorithm中的函数std::next_permutation(str.begin(), str.end()) 来解决此问题。
- 对于字符串转数字,这个就比较简单了,但是我是将string中第i, j之间的字符转化为数字(包括两端点),并非将传入参数的一个string类转化为数字,不然的话就又多了一个对于字符串的部分截取(虽然有相应的函数)
以下就是我的代码了
#include <iostream>
using namespace std;
#include <string>
#include <vector>
#include <algorithm>
string str = "123456789";//1~9个数字
int Exchange(int i, int j)//将str中第i, j之间的字符转化为数字(包括两端点)
{
int number = 0;
for (; i <= j ; i++)
{
number = number * 10 + str[i] - '0';
}
return number;
}
int main()
{
int i, j, k, num, sum = 0;
int a, b, c;
cin >> num;
while (next_permutation(str.begin(), str.end()))//全排列
{
for (i = 0 ; i <= 4 ; i++)//第一刀的选取
{
a = Exchange(0, i);
for (j = (8 - i) / 2 + i ; j < 8 ; j++)//第二刀的选取
{
b = Exchange(i + 1, j);
c = Exchange(j + 1, 8);
if (num == a + b / c && b % c == 0)//限制条件,不要忘了b % c == 0,不然b / c 同意也会得到一个值,但不满足题意
{
sum++;
}
}
}
}
cout << sum << endl;
return 0;
}
如有错误,麻烦指出!谢谢啦!