蓝桥杯带分数(全排列+剪枝)
问题描述
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
用next_permutation()函数生成1~9这9个数字组成的全排列。从所有的全排列中检查满足条件的。
注意剪枝,否则会超时。如何剪枝呢? 首先确定,给一个任意排列如何将该序列分为三块:m1,m2,m3。if(m1+m2/m3==m&&(m2%m3==0)) 成立,则结果加1.
从这个条件我们可以看出 :
1.m1<m
2.m1+m2/m3<=m
运用这两个剪枝条件即可A C
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int a[9]={1,2,3,4,5,6,7,8,9}; int n; int cnt; void judge() { int m1,m2,m3; for(int i=0;i<9;i++) { m1=0; for(int j=0;j<=i;j++) { m1*=10; m1+=a[j]; } if(m1>n) break; for(int j=i+(9-i)/2;j<8;j++) { m2=0; for(int x=i+1;x<=j;x++) { m2*=10; m2+=a[x]; } m3=0; for(int y=j+1;y<9;y++) { m3*=10; m3+=a[y]; } if(m3==0) break; if(m2/m3>n) break; if(m2%m3==0&&(m1+m2/m3)==n) { cnt++; } } } } int main() { scanf("%d",&n); do{ judge(); }while(next_permutation(a,a+9)); printf("%d\n",cnt); return 0; }
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步