蓝桥杯 带分数题解 (Java实现)
作者:互联网
文章目录
一、题目
带分数
100 可以表示为带分数的形式:100=3+69258/714
还可以表示为:100=82+3546/197
注意特征:带分数中,数字 1∼9 分别出现且只出现一次(不包含 0)。
类似这样的带分数,100 有 11 种表示法。
输入格式
一个正整数。
输出格式
输出输入数字用数码 1∼9 不重复不遗漏地组成带分数表示的全部种数。
数据范围
1≤N<106
输入样例1:
100
输出样例1:
11
输入样例2:
105
输出样例2:
6
二、思路题解
首先题目所说的1-9个数字,不重复,即隐含着实现1-9数字的全排列(因为全排列就是9个数字不重复,不遗漏)
全排列实现之后进行加号和除号的位置放置的选择,1-9九个数要实现A+B/C的形式,加号放置此时只能有7种(因为1-9只有8个空格,其中/号占据一个空格,所以+号进行插空只有7种),又+号和/号满足如下关系:
当+号放置在第一个空格时,/号只有7种选择
当+号放置在第二个空格时,/号只有6种选择
当+号放置在第三个空格时,/号只有5种选择
依次类推可以总结如下:
如果+号的选择为:for(int i=1;i<=7;i++)
则/号的选择为:for(int j=i+1;j<=8;j++)
之后进行A+B/C这种形式中A,B,C三个数创建,见下面代码中的cal函数
但在编程时需要注意一点,+号前面的数的值不能大于目标数,即我们输入的数。
插空思路如下图
三、代码实现
import java.util.*;
public class 带分数{
//定义全局变量
private static int[] arr = {1,2,3,4,5,6,7,8,9};
//static int[] arr = {1,2,3,4};
private static int cout=0;//进行计数
static int tar;//目标数字
//进行分段,求解A,B,C三个数值
static int cal(int s,int e){
int res=0;
for(int i=s;i<e;i++){
res = res*10+arr[i];
}
return res;
}
//全排列
static void perm(int[] arr,int q,int p){
if(q==p){//判断到最后一个元素时进行分段判断
//先进行加号+取段,根据上面的算术特征,加号只有7中位置选择
//
for(int i=1;i<=7;i++){
int a = cal(0,i);//加号前面的数字
//判断如果加号前面是数的数值大于所输出的数就直接退出
if(a>=tar) {//+号前面的数进行判断是否大于或等于目标数
continue;
}
//其次进行/除号判断,/号的选择与加号选择有如下关系
//当加号在第1个位置时,/号必有7中位置选择,即需要进行7次判断
//当加号在第2个位置时,/号必有6中位置选择,即需要进行6次判断
for(int j=i+1;j<=8;j++){
int b = cal(i,j);//这是判断分子的数值
int c = cal(j,9);//这是判断分母数值,共9个数字。即下标最高是8
if(a*c+b==tar*c){//因为是/除法运算时会出现向下取整的情况,则需要转化为乘法操作
cout++;
}
}
}
}else{
for(int i=q;i<arr.length;i++){
//元素放置首位
int temp = arr[i];
arr[i]=arr[q];
arr[q]=temp;
perm(arr,q+1,p);
//回溯
int tt = arr[i];
arr[i]=arr[q];
arr[q]=tt;
}
}
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
tar = sc.nextInt();
perm(arr,0,arr.length);
System.out.println(cout);
}
}
四、运行结果截图
标签:arr,int,题解,带分数,蓝桥,static,加号,100 来源: https://blog.csdn.net/weixin_46371813/article/details/113941576