问题描述
试题 历届试题 带分数
资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
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分别出现且只出现一次(不包含0), 那么利用一个一维数组来存储数组1~9即可,带分数的组成结构是一个数字加上两个数字的比例,所以很明显的形式是N=A+B/C,其中A一定小于数字N,B一定能整除C,根据这两个前提条件, 我们把数字1~9的所有排列组合情况求出来,然后逐个判断是否满足以上条件
下面的问题是如何得到所有的排列情况,也是本问题的难点,这里给出C++ STL库中有可用的全排列函数,针对本题情况给出对应示例:
int s[9]={1,2,3,4,5,6,7,8,9};
//进行前需要排好序
while(next_permutation(s,s+9)){
//每一个循环便是一个排列
//prev_permutation实现降序
}
利用标准库函数,解决本题的难度基本上约等于没有
答案
#include<iostream>
using namespace std;
#include<algorithm>
int number;
int s[9]={1,2,3,4,5,6,7,8,9};
int get(int n1,int n2){//包前不包后 //将下标从n1到n2的字符串转换为整数
int num=0;
for(int i=n1;i<n2;i++){
num=num*10+s[i];
}
return num;
}
int judge(){
int a=1;int b;
int number1;int number2;int number3;
while(a<7){
number1=get(0,a);
if(number1<number){
b=int((9-a)/2)+a;
while(b<9){
number2=get(a,b);
number3=get(b,9);
//cout<<number1<<" "<<number2<<" "<<number3<<endl;
if(number2%number3==0){
if(number==number1+(number2/number3)){
//匹配成功
return 1;
}
}
b++;
}
}
else{
break;
}
a++;
}
return 0;
}
int main(){
cin>>number;int time=0;
while(next_permutation(s,s+9)){
//if(s[0]!=0){
if(judge()==1){
time++;
}
}
cout<<time<<endl;
return 0;
}