问题描述
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
import java.util.Scanner;
import java.util.regex.*;
public class Main {
public static void main(String[] args) {
int count = 0 ;
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int t;//表示分子
//暴力搜索整数部分和分母
for(int i=1; i<n; i++){
//剪枝:有重复直接跳过
if(QuChong(i)) continue;
for(int j=1; j<1000; j++){
if(QuChong(j) || OverOne(i,j)) continue;//剪枝
t = (n - i) *j;
if(!QuChong(t) && !OverOne(j,t) && !OverOne(i,t)){
if((""+i+j+t).length() == 9){
count++;
}
}
}
}
System.out.println(count);
}
//判断是否重复如555含0
public static boolean QuChong(int a){
boolean has = false;
String s = "" + a;
//正则表达式判断是否有重复
String regex = "(\\d)\\d*\\1";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(s);
int index = s.indexOf('0');
if(m.find() || index != -1) has = true;
return has;
}
//判断是否一个数字多次出现
public static boolean OverOne(int a, int b){
boolean pd = false;
String s = "" + a;
String ss = "" + b;
for(int i=0; i<s.length(); i++){
int index = ss.indexOf(s.charAt(i));
if( index != -1) {
pd = true;
break;
}
}
return pd;
}
}
时间复杂度有点大,需要再完善一下。思路:就是暴力搜索整数部分和分母,从而倒推出分子。分子如果是1-9中除整数和分母剩下的数组成,且一个数只出现一次。则分子符合标准,那么我们暴力搜索出的就是合理答案。count++。