100 可以表示为带分数的形式:100 = 3 + 69258 / 714
还可以表示为:100 = 82 + 3546 / 197
注意特征:带分数中,数字1~9分别出现且只出现一次(不包含0)。
类似这样的带分数,100 有 11 种表示法。
题目要求:
从标准输入读入一个正整数N (N<1000*1000) 程序输出该数字用数码1~9不重复不遗漏地组成带分数表示的全部种数。
注意:不要求输出每个表示,只统计有多少表示法!
例如:
用户输入:
100
程序输出:
11
再例如:
用户输入:
105
程序输出:
6
资源约定:
峰值内存消耗 < 64M CPU消耗 < 3000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main函数需要返回0 注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。 注意: 所有依赖的函数必须明确地在源文件中 #include , 不能通过工程设置而省略常用头文件。
提交时,注意选择所期望的编译器类型。
枚举排列,然后划分为三组判断。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> using namespace std; int n,num,c; int vis[10]; int xl[10]; void check() { for(int i = 1;i <= num;i ++) { int a = 0; for(int j = 0;j < i;j ++) { a = a * 10 + xl[j]; } if(a < n) for(int j = (9 - i + 1) / 2 + i;j < 9;j ++) { int x = 0,y = 0; for(int k = i;k < j;k ++) { x = x * 10 + xl[k]; } for(int k = j;k < 9;k ++) { y = y * 10 + xl[k]; } if(x % y == 0 && a + x / y == n) { c ++; } } } } void dfs(int k) { if(k >= 9) { check(); return; } for(int i = 1;i < 10;i ++) { if(!vis[i]) { vis[i] = 1; xl[k] = i; dfs(k + 1); vis[i] = 0; } } } int main() { scanf("%d",&n); num = log10(n) + 1; dfs(0); printf("%d",c); }
import java.util.Scanner; public class Main { private static Scanner sc = new Scanner(System.in); private static int n; private static int [] ans = new int[10]; private static boolean [] vis = new boolean[10]; private static int c = 0; private static void check() { for(int i = 1;i < 9;i ++) { int d = 0; for(int j = 0;j < i;j ++) { d = d * 10 + ans[j]; } if(d < n) for(int j = (i + 8) / 2;j < 9;j ++) { int e = 0,f = 0; for(int k = i;k < j;k ++) { e = e * 10 + ans[k]; } for(int k = j;k < 9;k ++) { f = f * 10 + ans[k]; } if(e % f == 0 && e / f + d == n) c ++; } } } private static void dfs(int k) { if(k >= 9) { check(); } for(int i = 1;i <= 9;i ++) { if(!vis[i]) { vis[i] = true; ans[k] = i; dfs(k + 1); vis[i] = false; } } } public static void main(String[] args) { n = sc.nextInt(); dfs(0); System.out.println(c); } }