Java习题练习:带分数
- 题目
- 题目分析
- 源代码
- 代码解析
这道题是2013年第四届蓝桥杯 Java A组省赛第八题带分数
题目
100 可以表示为带分数的形式:100 = 3 + 69258 / 714
还可以表示为:100 = 82 + 3546 / 197
注意特征:带分数中,数字1~9分别出现且只出现一次(不包含0)。
类似这样的带分数,100 有 11 种表示法。
题目要求:
从标准输入读入一个正整数N (N<1000*1000)
程序输出该数字用数码1~9不重复不遗漏地组成带分数表示的全部种数。
注意:不要求输出每个表示,只统计有多少表示法!
例如:
用户输入:
100
程序输出:
11
再例如:
用户输入:
105
程序输出:
6
资源约定:
峰值内存消耗(含虚拟机) < 64M
CPU消耗 < 3000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.6及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。
题目分析
读完题目,我们想到把这九个数进行全排列,然后进行分割遍历。
那么怎么进行全排列呢?这个是有模板的。我们把九个数存到一个数组里面,然后进行递归即可。
模板如下:
//确定某一个排列的第k位
private static void f(int[] arr,int k) {
if(k==9) {//全部确认
check(arr);
return;//return 来结束
}
//选定第k位
for(int i=k;i<arr.length;i++) {
//将第i位与第k位交换
int t=arr[i];
arr[i]=arr[k];
arr[k]=t;
//移交下一层去确认k+1位
f(arr,k+1);
//回溯(换回来)
t=arr[i];
arr[i]=arr[k];
arr[k]=t;
}
}
模板特征:
传入:一个数组,一个下标。
一般情况下:下标传进时为0,当下标超出数组最大下标时return。
有一个for循环进行排列,里面有两个swap功能的小模块,两校模块中间有递归功能的f(arr,k+1);
源代码
import java.util.Scanner;
public class Main {
static int ans;
private static int N;
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in=new Scanner(System.in);
N=in.nextInt();//这里不能用int
int[] arr={1,2,3,4,5,6,7,8,9};
f(arr,0);
System.out.println(ans);
}
//确定某一个排列的第k位
private static void f(int[] arr,int k) {
if(k==9) {//全部确认
check(arr);
return;
}
//选定第k位
for(int i=k;i<arr.length;i++) {
//将第i位与第k位交换
int t=arr[i];
arr[i]=arr[k];
arr[k]=t;
//移交下一层去确认k+1位
f(arr,k+1);
//回溯(换回来)
t=arr[i];
arr[i]=arr[k];
arr[k]=t;
}
}
private static void check(int[] arr) {
for(int i=1;i<=7;i++) {
int num1=toInt(arr,0,i);//+号前面的一段整数
if(num1>=N) return;//如果此时+号的数额超过了N,就没必要验算了
//前面的字符数
for(int j=1;j<=8-i;j++) {
int num2=toInt(arr,i,j);
int num3=toInt(arr,i+j,9-i-j);
if(num2%num3==0&&num1+num2/num3==N) {
ans++;
}
}
}
}
private static int toInt(int[]arr,int pos,int len) {
int t=1;
int ans=0;
for(int i=pos+len-1;i>=pos;i--) {
ans+=arr[i]*t;
t*=10;
}
return ans;
}
}
代码解析
第4行 static int ans;
第5行 private static int N;
这里是定义两个全局变量,其中static一定要写,private可以不写
第9行 N=in.nextInt();//这里不能用int
这里不能声明int了,因为已经在全局变量里面声明过了。
如果还声明int,那么这个int就是局部变量,那么被赋值的,就是这个局部变量,全局变量没有被赋值。
第40行 for(int i=1;i<=7;i++)
这个i是下标i,如果因为是9个数字,则最大下标为8,则 i 前面的数组数字进行计算成整数。
在check这两个循环中,我们采用极限思维方法,令i=7,其他的循环脸面的边界条件就好求了
注意toInt函数中,pos就是下标,len就是长度