蓝桥杯-带分数(枚举)

带分数:http://lx.lanqiao.org/problem.page?gpid=T26

问题描述

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


刚开始也想过dfs枚举全排列,但觉得和循环差别不大,就直接用循环了

n=i+((n-i)*j)/j

枚举i和j,判断i,j,(n-i)*j是否满足题目要求即可




#include <cstdio>
#include <algorithm>

using namespace std;

int n,ans,a[11],atop,t,b[11],btop,c[11],ctop,num,tmp;
bool used[11];

bool judge(int x[],int& xtop) {
    while(t) {
        if(used[t%10])
            return false;
        used[x[++xtop]=t%10]=true;
        t/=10;
    }
    return true;
}

bool isOK() {
    for(int i=1;i<10;++i)
        if(!used[i])
            return false;
    return true;
}

int main() {
    int i,j;
    for(i=0;i<11;++i)
        used[i]=false;
    used[0]=true;
    while(1==scanf("%d",&n)) {
        ans=0;
        for(i=1;i<n;++i) {
            atop=-1;
            t=i;
            if(judge(a,atop)) {
                num=n-i;
                for(j=1;j<10000&&(tmp=num*j)<98765432;++j) {//【注意】num*j有可能爆int,本地测试n=1000000都运行错误,提交却AC,不知是否是没出极限数据
                    btop=-1;
                    t=j;
                    if(judge(b,btop)) {
                        t=tmp;
                        ctop=-1;
                        if(judge(c,ctop)&&isOK())
                            ++ans;
                        while(ctop>=0)//这些复原本来可以复制副本,最后拷会去即可,结果只想到更麻烦的方法
                            used[c[ctop--]]=false;
                    }
                    while(btop>=0)
                        used[b[btop--]]=false;
                }
            }
            while(atop>=0)
                used[a[atop--]]=false;
        }
        printf("%d\n",ans);
    }
    return 0;
}


你可能感兴趣的:(枚举,蓝桥杯)