蓝桥杯 带分数

问题描述

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

可以直接枚举1-9的所有排列,再对排列进行划分。生成排列可以自己写一个函数,也可以直接用STL中的next_permutation
[cpp]  view plain copy
  1. #include<cstdio>  
  2. #include<iostream>  
  3. #include<algorithm>  
  4. using namespace std;  
  5. int set[]={1,2,3,4,5,6,7,8,9};  
  6. int tot=0;  
  7.   
  8. int getnum(int n,int m){  
  9.     int num=0;  
  10.     for(int i=n;i<=m;i++)  
  11.     num=set[i]+num*10;  
  12.     return num;  
  13. }  
  14.   
  15. int main(){  
  16.     int n;  
  17.     cin>>n;    
  18.     do{  
  19.         int a=0,b=0,c=0,bl=0;  
  20.         for(int i=0;i<8;i++){  
  21.             a=getnum(0,i);  
  22.             for(int j=i+1;j<8;j++){  
  23.                 b=getnum(i+1,j);  
  24.                 c=getnum(j+1,8);  
  25.                 if(b%c==0&&n==a+b/c){  
  26.                     tot++;break;  
  27.                 }  
  28.             }  
  29.         }  
  30.     }while(next_permutation(set,set+9));  
  31.     cout<<tot;  
  32.     return 0;  
  33. }  



上面的算法虽然提交后并未超时,但是还有很多地方可以优化。参考 KeepThinking_ 的方法进行优化后如下:
[cpp]  view plain copy
  1. #include<cstdio>  
  2. #include<iostream>  
  3. #include<algorithm>  
  4. using namespace std;  
  5. int set[]={1,2,3,4,5,6,7,8,9};  
  6. int tot=0;  
  7. int x=0;  
  8.   
  9. int getnum(int n,int m){  
  10.     int num=0;  
  11.     for(int i=n;i<=m;i++)  
  12.     num=set[i]+num*10;  
  13.     return num;  
  14. }  
  15.   
  16. int main(){  
  17.     int n;  
  18.     cin>>n;  
  19.     int temp=n;  
  20.     while (temp != 0)        
  21.     {    
  22.         ++x;    
  23.         temp /= 10;    
  24.     }    
  25.       
  26.     do{  
  27.         int a=0,b=0,c=0,bl=0;  
  28.         for(int i=0;i<x;i++){  
  29.             a=getnum(0,i);  
  30.             bl=((n-a)*set[8])%10;  
  31.              for (int j =i+(8-i)/2; j < 8; j++){  
  32.                 if(set[j]==bl){  
  33.                     b=getnum(i+1,j);  
  34.                     c=getnum(j+1,8);  
  35.                     if(n==a+b/c&&b%c==0){  
  36.                         tot++;break;  
  37.                      }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值