问题描述
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; }
原文地址:https://www.cnblogs.com/woxiaosade/p/10320975.html
时间: 2024-11-05 16:30:23