zoukankan      html  css  js  c++  java
  • 历届试题 带分数

    问题描述

    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
    思路一:
    全排列列出所有的情况,求出满足条件的个数,不过会超时,这时要剪枝
    如何建造好的剪枝条件?
    本题说的是,n=a+b/c;那么首先a一定是小于n的,又因为n为整数,所以a和b/c都是整数,这就要求
    b/c一定可以整除,所以b%c=0,b/c还要满足可除条件,即b>=c。剪枝的三个条件已经确定
    (1).a<n;
    (2).b%c=0;
    (3).b>=c
    再加上n=a+b/c就是四个条件了。只要在1至9的全排列中选取满足这四个条件的全排列就是所求的结果之一。
    那么在1至9的全排列(9个数字)中如何确定a,b,c的取值范围呢?
    a前面已经说过,而又知道,b一定大于或等于c,则b的取值范围一定在a选择过后去选择剩下的一半或一半以上的数据。举个例子,1至9的其中一个全排列--156987423,若a选择156,则b只能选择剩下的987423中的一半或
    一半以上,如987、9874、98742。如果b小于剩下的一半,那么一定不满足除法(如98/7432)。c
    的范围则是a和b选择剩下的所有了。这样我们就可以判定,假设num=9,a选择9位中的前n位,那
    么b的结尾选择范围为第n+(num-n)/2至num-1位数字(结尾为一半或一半以上,最多时到num-1
    ,给c留一个数字);
    那么利用深度优先搜索(用来得到一个9位的全排列)和适当的判断(剪枝,找出符合3个条件并
    且满足n=a+b/c的全排列)就可以解决。
    下面是我写的两个版本的代码
    版本一 (超时)
     1 import java.util.Scanner;
     2 import java.util.concurrent.atomic.LongAccumulator;
     3 
     4     public class Main{
     5         public static int num=0;
     6         public static int[]array=new int[10];
     7         static int res;
     8         static int length=0;
     9         public static void main(String[] args){ 
    10             Scanner scanner=new Scanner(System.in);
    11             String th=scanner.next();
    12              res=Integer.parseInt(th);
    13             length=th.length();
    14             for (int i = 1; i <=array.length-1; i++) {
    15                 array[i]=i;
    16             }
    17             long a=System.currentTimeMillis();
    18             perm(array,1, 9);
    19             System.out.println(num);
    20             long b=System.currentTimeMillis();
    21           // System.out.println(b-a);
    22             
    23         }
    24        public static void Swap(int str[], int a, int b)
    25         {
    26            int temp = str[a];
    27             str[a] = str[b];
    28             str[b] = temp;
    29         }
    30         public static void perm(int array[],int k,int m)
    31         {
    32             if(k==m) {
    33                 String string="";
    34                 for (int i = 1; i <=array.length-1; i++) {
    35                     string+=array[i];
    36                 }
    37                 String a="";
    38                 String b="";
    39                 String c="";
    40                 //int num1=Integer.parseInt(string);
    41                 for (int i = 1; i <string.length()-1; i++) {
    42                     a=string.substring(0, i);
    43                     int a1=Integer.parseInt(a);
    44                     if(a1>res) break;
    45                     for (int j = i+(9-i)/2; j < string.length(); j++) {
    46                         
    47                         b=string.substring(i,j);
    48                         c=string.substring(j,string.length());
    49                         
    50                 
    51                         
    52                         int a2=Integer.parseInt(b);
    53                         int a3=Integer.parseInt(c);
    54                         if(a3>a2) continue;
    55                         if(a2%a3==0) {
    56                             if(a1+a2/a3==res) {
    57                                 num++;
    58                             }
    59                         }
    60                     }
    61                 }
    62             return;
    63  
    64             }else {
    65                 for (int i = k; i <=m; i++) {
    66                     Swap(array, i, k);
    67                     perm(array,k+1,m);
    68                     Swap(array, i, k);
    69                 }
    70             }
    71             
    72             
    73         }
    74       
    75  }

    版本二(正确)

     1 import java.util.Scanner;
     2 import java.util.concurrent.atomic.LongAccumulator;
     3     public class Main{
     4         public static int num=0;
     5         public static int[]array=new int[10];
     6         static int res;
     7         static int length=0;
     8         public static void main(String[] args){ 
     9             Scanner scanner=new Scanner(System.in);
    10             String th=scanner.next();
    11                long a=System.currentTimeMillis();
    12              res=Integer.parseInt(th);
    13             length=th.length();
    14             for (int i = 1; i <=array.length-1; i++) {
    15                 array[i]=i;
    16             }
    17          
    18             perm(array,1, 9);
    19             System.out.println(num);
    20             long b=System.currentTimeMillis();
    21           //  System.out.println(b-a);//显示运行时间,单位ms
    22             
    23         }
    24        public static void Swap(int str[], int a, int b)
    25         {
    26            int temp = str[a];
    27             str[a] = str[b];
    28             str[b] = temp;
    29         }
    30        public static int sumNUm(int array[],int start,int end)
    31        {
    32            int sum=0;
    33            for (int i = start; i <=end; i++) {
    34             sum=sum*10+array[i];
    35             
    36         }
    37            return sum;
    38        }
    39         public static void perm(int array[],int k,int m)
    40         {
    41             if(k==m) {
    42                 for (int i = 1; i <array.length-2; i++) {
    43                     int a=sumNUm(array, 1, i);
    44                     if(a>res) break;
    45                     for (int j = i+(9-i)/2; j <array.length-1; j++) {
    46                         int b=sumNUm(array, i+1, j);
    47                         int c=sumNUm(array, j+1, m);
    48                         if(c>b) continue;
    49                         if(b%c==0&& b/c+a==res) {
    50                             //System.out.println(a+"+"+b+"/" + c);
    51                             num++;
    52                         }
    53                     }
    54                 }
    55                 
    56             }else {
    57                 for (int i = k; i <=m; i++) {
    58                     Swap(array, i, k);
    59                     perm(array,k+1,m);
    60                     Swap(array, i, k);
    61                 }
    62             }
    63             
    64             
    65         }
    66       
    67  }

     两个版本思路完全一样,不同的是版本一的代码把数组变成了字符串,再进行拆分不同数字,结果超时,充分说明了计算机对字符串的处理速度是比较慢的,所以以后在使用字符串时要注意效率和速度。

    思路二

    可以参考这篇博客https://blog.csdn.net/zhangpengyu321/article/details/8964803

    没有用到全排列的一种暴力手段,也不会超时。

  • 相关阅读:
    第一章 ASP.net C#基本语法(A篇 变量) 王道
    yarn和npm常用命令
    新的开始 Pit
    mysql关键字执行顺序
    log4j2.14.0漏洞攻击复现
    elastic search why so good?
    C# 使用网易126邮箱发件和收件
    分享
    再也没有人......
    数据库附加不上 未能在sysindexes中。。。
  • 原文地址:https://www.cnblogs.com/henuliulei/p/10431319.html
Copyright © 2011-2022 走看看