历届试题 带分数

问题描述

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
思路
  使用C++自带的next_permutation()函数求得全排列
  写一个found()判断一个排列有几个满足要求的组合
    适当的剪枝
      1. 第一个数必须 <= n
      2. 第二个数必须 >= n
      3. 第二个数 % 第三个数 ==0
    get_num(int m, int n)函数 获取数组第m到第n位组成的数
注意事项
  尽量简化函数,小地方可能会引发超时。
int get_num(int m,int n){
    int t = 0;
    for(int i = n;i >= m;i--)
        t += a[i]*pow(10,i - m);
    return t;
}//第m个数字到第n个数字 

int get_num(int m,int n){
    int t = 0;
    for(int i = n;i >= m;i--)
        t = t*10 + a[i];
    return t;
}//第m个数字到第n个数字 

  上面的两个get_num()函数,第二个的效率远高于第一个。pow()函数的本质是循环。

  循环能舍则舍!

附AC代码

#include <iostream>
#include <cstdio>
#include <stdio.h>
#include <algorithm>
#include <stdlib.h>
#include <string.h>
#include <cmath>
#include <time.h>
using namespace std;
int sum = 0;
int n;
int a[9] = {1,2,3,4,5,6,7,8,9};
int get_num(int m,int n){
    int t = 0;
    for(int i = n;i >= m;i--)
        t = t*10 + a[i];
    return t;
}//第m个数字到第n个数字 
void found(){
    for(int i=0;i<9;i++){
        int t1 = get_num(0,i);
        if(t1 > n)
            return;
        for(int j = 8;j>i;j--){
            int t2 = get_num(i+1,j-1);
            int t3 = get_num(j,8);
            //cout<<t1<<" "<<t2<<" "<<t3<<endl;
            if(t2>=t3 && t2%t3 == 0 &&(t1 + t2 / t3) == n)
                sum++;
        }
    }
}
int main(){
    scanf("%d",&n);
    found();
    while(next_permutation(a,a+9))
        found();
    printf("%d\n",sum);
    return 0;
}
扫描二维码关注公众号,回复: 5067177 查看本文章

猜你喜欢

转载自www.cnblogs.com/woxiaosade/p/10320975.html