历届试题 带分数
时间限制:1.0s 内存限制:256.0MB
问题描述
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
思路:标的分类有时候会误导人。使用什么方法还是要有自己的判断,不能光靠提示往那方面去想。
受到分类的影响用枚举,可以过三个测试数据,但是1000000以内的有些数可能会超时,这里的枚举不是毫无技巧地枚举而是全排列后再枚举。
更好的方法可以用全排列1-9,然后按顺序分成三个数,再判断是否可以满足条件。
#include <iostream> #include <cstdio> #include <vector> #include <queue> #include <cstring> #include <algorithm> #include <cstdlib> #define FOR(i,x,n) for(long i=x;i<n;i++) #define ll long long int #define INF 0x3f3f3f3f #define MOD 1000000007 #define MAX_N 50005 using namespace std; int a[11]; int cou=0; bool check(){ if(a[0]>0){ return false; } FOR(i,1,10){ if(a[i]>1||a[i]==0){ return false; } } return true; } void record(int aa){ while(aa){ int t=aa%10; a[t]++; aa/=10; } } bool jud(int aa){ int b[11]={0}; while(aa){ int t=aa%10; b[t]++; if(b[t]>1){ return false; } aa/=10; } return true; } int main() { //freopen("data.txt", "r", stdin); //freopen("data.out", "w", stdout); long n; scanf("%d",&n); cou=0; FOR(i,1,n){ if(jud(i)){ FOR(j,1,5000){ if(jud(j)){ fill(a,a+11,0); record(i); record(j); int t=j*n-i*j; record(t); if(check()){ cou++; } } } } } printf("%d ",cou); //fclose(stdin); //fclose(stdout); return 0; }