历届试题 带分数
时间限制:1.0s 内存限制:256.0MB
提交此题 锦囊1 锦囊2
问题描述
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看成一个长度为9的字符型数组,作全排列并保存结果。对每一个全排列结果 的不同位置尝试插入“+”号和“/”号,并转换成数学式计算结果,若计算结果等于输入数字则结果+1.
JAVA代码:
import java.util.Scanner;
public class Main {
static int pos=0;
static int m;
static int answer=0;
static int register[]=new int [362880];//362880是九个数字的全排列个数
public static void main(String []args)
{
Scanner cs = new Scanner(System.in);
m=cs.nextInt();
char G[]="123456789".toCharArray();
f(G,0); //求9个数字的全排列
//判断输入数的位数
int wei=0;
int temp=m;
for(int i=0;i<7;i++){ //先计算输入数的位数,可以省去后面一些不必要的计算
m/=10;
if(m==0){
wei=i+1;
break;
}
}
m=temp;
for(int i=0;i<362880;i++){ //对每个全排列结果都算一次
calculate(i,wei);
}
System.out.println(answer);
}
static void calculate(int suiji,int wei){ //核心算法
int sourse=register[suiji];
//插入“+”号
int one=sourse;
for(int i=1;i<=wei;i++){
int ten=1;
for(int j=0;j<i;j++){
ten*=10;
}
one=sourse%ten;//one 作为“+”号前的数
if(one>=m){
break;
}
//插入"/"号
int left=sourse/ten;//去掉“+”号前的数剩下的部分
int fengzi=left/10;
int fengmu=left%10;
int ten1=10;
while(fengzi>fengmu){
if(fengzi%fengmu==0){
if(fengzi/fengmu+one==m){
answer++;
}
}
ten1*=10;
fengzi=left/ten1;
fengmu=left%ten1;
}
}
}
static void f(char[] data ,int k){ //求全排列
if(k==data.length){
String str= String.valueOf(data);
register[pos++] = Integer.parseInt(str);
}
for(int i=k;i<data.length;i++){
char t=data[k];//试探
data[k]=data[i];
data[i]=t;
f(data,k+1);//递归
t=data[k];//回溯
data[k]=data[i];
data[i]=t;
}
}
static int jiecheng(int n){ //求阶乘
int result=1;
for(int i=1;i<=n;i++){
result*=i;
}
return result;
}
}