问题描述
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 使用了STL(为蓝桥杯历届真题解析课程的解法):
但我觉得这博客写的更好:
蓝桥杯 历年真题 带分数(全排列切割)–作者DeathYmz
#include <iostream>
#include<string>
#include<algorithm>
#include <stdio.h>
using namespace std;
int parse(const char* arr, int pos, int len) {
int ans = 0;
int t = 1;
for (int i = pos + len - 1; i >= pos; i--)
{
ans += (arr[i] - '0') * t;
t *= 10;
}
return ans;
}
int main() {
int N;
cin >> N;
int ans = 0;
string s = "123456789";
do
{
const char* str = s.c_str();
for (int i = 0; i <= 7; i++)//i <= 7,因为intb,intc至少要一位
{
//string a = s.substr(0, i);
//获取字符串s在o~i的子串
//反复截取字符串,需要消耗很大的内存
//int inta = atoi(a.c_str());
//atoi是#include <stdlib.h>中的,意思为字符串转整形
int inta = parse(str, 0, i);
//完成了上面注释的两个代码,同时对内存消耗减少了
if (inta >= N)break;
for (int j = 1; j <= 9 - 1 - i; j++)
//int j = 1,因为intb至少要一位
//j <= 9 - 1 - i,因为总共9位,inta为i位,intc至少一位(当然,写成 j <= 9,这里的是做了些优化)
{
//string b = s.substr(i, j);
//s.substr(i,j)表示从下标为i的位置开始截取j位
//string c = s.substr(i + j);
//s.substr(i + j)表示从下标i + j开始一直到字符串结束
//int intb = atoi(b.c_str());
//int intc = atoi(c.c_str());
int intb = parse(str, i, j);
int intc = parse(str, i + j, 9 - i - j);
if (intb % intc == 0 && inta + intb / intc == N)
{
/*cout << inta << " " << intb << " " << intc << " " << endl;*/
ans++;
}
}
}
} while (next_permutation(s.begin(), s.end()));
//next_permutation(s.begin(), s.end())是STL中的全排列
cout << ans;
return 0;
}
代码2(自己通过dfs写全排列的部分):
#include<iostream>
#include<string.h>
using namespace std;
int visit[10] = { 0 };//作为是否已被取的标志
int s[10];
int ans = 0;
int N;
void found(int s[])//目的,得到满足条件的x,y,z
{
int x, y, z;
for (int i = 1; i < 9; i++)//对于要对三个变量,在一个范围内,可参考下面的方式
{
for (int j = i + 1; j < 9; j++)
{
x = y = z = 0;
for (int k = 0; k < 9; k++)
{
if (k < i)x = x * 10 + s[k + 1];
else if (k < j)y = y * 10 + s[k + 1];
else z = z * 10 + s[k + 1];
}
if (y % z == 0 && x + y / z == N)
{
/*cout << x << " " << y << " " << z << " " << endl;*/
ans++;
}
}
}
}
void dfs(int pos, int n)//通过dfs(深度搜索),得到1~9的全排列
{
if (pos == n)
found(s);
else
{
for (int i = 1; i <= 9; i++)
{
if (!visit[i])
{
s[pos] = i;
visit[i] = 1;
dfs(pos + 1, n);
visit[i] = 0;
}
}
}
}
int main()
{
cin >> N;
dfs(1, 10);
cout << ans << endl;
return 0;
}
欢迎任何形式的转载,但请务必注明出处。
限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。