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

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

  • 相关阅读:
    hdu 4521 小明系列问题——小明序列(线段树 or DP)
    hdu 1115 Lifting the Stone
    hdu 5476 Explore Track of Point(2015上海网络赛)
    Codeforces 527C Glass Carving
    hdu 4414 Finding crosses
    LA 5135 Mining Your Own Business
    uva 11324 The Largest Clique
    hdu 4288 Coder
    PowerShell随笔3 ---别名
    PowerShell随笔2---初始命令
  • 原文地址:https://www.cnblogs.com/henuliulei/p/10431319.html
Copyright © 2011-2022 走看看