蓝桥杯 历届试题 带分数

来源:互联网 发布:修真淘宝大户 编辑:程序博客网 时间:2024/06/05 06:06

问题描述
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

http://lx.lanqiao.cn/problem.page?gpid=T26

对于这个题 第一个想到的肯定是枚举
就是 假如是100 的话 那么
就是 a+b/c a枚举到1到99
然后枚举c - -
这样的量是非常大的 。
假如是10^5
a枚举的数量就是1到10^5,直接就gg了。
所以肯定不能枚举。

然后题目要求
可以确定一个条件。
a+b/c =n;
a,b,c组成的串是1到9各出现一次的。
换句话说 abc组成的串是属于 1到9 的全排列的集合中的一个元素。
如果用枚举的话,会枚举处很多无用的条件,
但是 ,我们把集合确定到全排列集合内部。
在全排列的内部去寻找,那么确定每一步都是有用功的。
就是每一步也不浪费。

1到9的全排列。
搜索搜出来的数量为362880个
对于每个全排列 我们只需要划分处a,b,c
a是代表一个全排列的前几位,b是接着的几位。c是剩下的几位。
只需要判断b%c==0 的话 那么a+b/c就组成了一个数字。
那么dp【a+b/c】++;
对于每个排列的枚举数量 a枚举7次。b枚举7次。c是剩下的全加。
这样 总操作次数喂362880*49 +362880 的粗略值。
也就是2000万内能找出所有的dp【a+b/c】;

并且每一步都是有用功的。
因为寻找一个数的a+b/c 和寻找所有数的a+b/c,都需要遍历所有排列。
所以 记录所有☞就可以

#include<iostream>#include<string>#include <algorithm>#include <cstring>#include <cmath>#include <map>#include <cstdio>using namespace std;int d[10];//搜索的动态标记int tag[10];//全排列的标记int sum;//记录全排列数量int dp[10000005];//记录结果int sss;//记录程序总共操作次数void run()//枚举一个全排列钟所有的a+b/c;{    int x=0,y=0,z=0;    for(int i=1;i<=9;i++)    {        sss++;        x=x*10+tag[i];        y=0;        for(int j=i+1;j<=9;j++)        {            sss++;            y=y*10+tag[j];            z=0;            //cout<<i<<' '<<j<<' '<<endl;            if(j-i>=9-j&&j<9)            {                sss++;                for(int k=j+1;k<=9;k++)                {                    z=z*10+tag[k];                }               //cout<<x<<' '<<y<<' '<<z<<' '<<x<<' '<<y/z<<endl;               if(z==0||y<z) continue;               if(y%z==0) dp[x+y/z]++;            }        }    }}void bfs(int t,int x,int s)//搜索全排列的排列{    tag[x]=s;    if(t==9)    {        run();        //for(int i=1;i<=9;i++)cout<<tag[i]<<' ';cout<<endl;        sum++;    }    for(int i=1;i<=9;i++)    {        sss++;        if(d[i]==0)        {            d[i]=1;            bfs(t+1,x+1,i);            d[i]=0;        }    }}int main(){    sss=0;    sum=0;    bfs(0,0,0);    //cout<<sum<<endl;    //cout<<sss<<endl;    int n;    while(cin>>n)    {        cout<<dp[n]<<endl;    }}
0 0
原创粉丝点击