带分数 --三种方法详解
来源:第四届蓝桥杯省赛C++B/C组,第四届蓝桥杯省赛JAVAA/B组
先粘题:
带分数
100 可以表示为带分数的形式:
还可以表示为:
注意特征:带分数中,数字 1~9分别出现且只出现一次(不包含 00)。
类似这样的带分数,100 有 11 种表示法。
输入格式
一个正整数。
输出格式
输出输入数字用数码 1~9不重复不遗漏地组成带分数表示的全部种数。
数据范围
1≤N<10^6
输入样例1:
100
输出样例1:
11
输入样例2:
105
输出样例2:
6
分析 :
这道题要我们用光1~9的数字 然后还不让我们有重复数字 来满足这个式子 我的思路是先全排列 然后check检测结果是否满足 但是注意这道题有个坑 带分数里的分数不一定是真分数 结果是整数也可能是浮点数 所以我们要变成乘法来判断 即:将n=a+b/c转换为n*c=a*c+b 这里也可以再转换成 b = n*c-a*c (注意b要开longlong型 不然会越界) 这样我们可以check求出的b 看看b是否存在已经使用过的数字
方法1:使用dfs嵌套 搜索树a 把a的每一个叶子节点都扩展成一棵搜索树(枚举c) 搜完c之后 最后再判断一下 b是否成立
代码:
#include <iostream>
#include <algorithm>
#include <cstring>using namespace std;
typedef long long ll;const int N = 20;bool st[N],backup[N];
int n,cnt;
bool check(int a, int c)
{ll b = n * ( ll )c - c * a; //因为 n*c 可能会溢出int从而变成负数, 所以使用long longif(!a || !b || !c) return false;memcpy(backup, st, sizeof st); //为了不影响之后dfs操作 需要复制一份当前st值用来检验bwhile(b){int x = b % 10;b /= 10;if(!x || backup[x]) return false; //检查是否存在已经用过的backup[x] = true;}for(int i = 1; i <= 9; i++){if(!backup[i]) return false; //检查是否存在没有用的}return true;
}void dfs_c(int u,int a,int c){if(check(a,c)) cnt++;for(int i=1;i<=9;i++){if(!st[i]){st[i]=true;dfs_c(u+1,a,c*10+i);st[i] = false;}}
}void dfs_a(int u,int a){if(a>n) return; //a不可能比n大dfs_c(u,a,0);for(int i=1;i<=9;i++){if(!st[i]){st[i]=true;dfs_a(u+1,a*10+i);st[i] = false;}}
}
int main(){cin.tie();cin>>n;dfs_a(0,0); ///a的搜索树 第一个参数表示当前进行到哪一个位置 第二个参数表示数字a的值cout<<cnt;
}
运行时间:1443ms
方法二:单层dfs 递归实现1~9的全排列 再对排列好的一串数字切分 判断是否满足条件
#include <iostream>using namespace std;const int N = 10;int target; //题目给出的目标数
int num[N]; //保存全排列的结果
bool used[N]; //生成全排列过程中标记是否使用过
int cnt; //计数,最后输出的结果//计算num数组中一段的数是多少
int calc(int l, int r){int res = 0;for(int i = l; i <= r; i++)res = res * 10 + num[i];return res;
}//生成全排列
//当全排列生成后进行分段
void dfs(int u){//用两层循环分成三段if(u == 9){for(int i = 0; i < 7; i++)for(int j = i + 1; j < 8; j++){int a = calc(0, i);int b = calc(i + 1, j);int c = calc(j + 1, 8);//注意判断条件,因为C++中除法是整除,所以要转化为加减乘来计算if(a * c + b == c * target) cnt++;}return;}//搜索模板for(int i = 1; i <= 9; i++)if(!used[i]){used[i] = true; //标记使用num[u] = i;dfs(u + 1);used[i] = false; //还原现场}
}int main(){scanf("%d", &target);dfs(0);printf("%d\n", cnt);return 0;
}
运行时间:3392ms
方法三:是方法二的一个升级 使用了c++自带stl模板algorithm中的方法 next_permutation() 大大减少了代码量
#include <iostream>
#include <algorithm>using namespace std;int n; //题目给出的目标数
int num[9]={1,2,3,4,5,6,7,8,9};
int cnt; //计数,最后输出的结果//计算num数组中一段的数是多少
int calc(int l, int r){int res = 0;for(int i = l; i <= r; i++)res = res * 10 + num[i];return res;
}//生成全排列
//当全排列生成后进行分段
void f(){while(next_permutation(num,num+9)){for(int i=0;i<7;i++){for(int j=i+1;j<8;j++){int a = calc(0,i);int b = calc(i+1,j);int c = calc(j+1,8);if(a * c + b == c * n) cnt++;}}}
}int main(){scanf("%d", &n);f();printf("%d\n", cnt);return 0;
}
运行时间:3291ms
易错点:next_permutation(start,end) 方法中的参数是左闭右开范围
带分数 --三种方法详解相关推荐
- python 命令-python解析命令行参数的三种方法详解
这篇文章主要介绍了python解析命令行参数的三种方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 python解析命令行参数主要有三种方法: ...
- 查看登陆系统用户的信息的三种方法详解
查看登陆系统用户的信息的三种方法详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.who这个命令显示可以谁在登陆,但是这个有很多的花式玩法,这个命令超简单 语法:who [O ...
- C语言求最大公约数三种方法详解
C语言求最大公约数三种方法详解 题目要求 常用写法(穷举法) 辗转相减法 辗转相除法 main函数 整体代码 题目要求 运行最大公约数的常用算法,并进行程序的调式与测试. 常用写法(穷举法) 从两个数 ...
- 新浪微博怎么推广引流,微博推广引流的三种方法详解
新浪微博怎么推广引流,微博推广引流的三种方法详解,#推广#营销 微博营销有哪些特点?#百收网SEO@千行助推 大家好,上一次内容讲了生意人如何将客户引流到自己的微信上去,受到很多朋友的喜爱,那么这一期 ...
- eclipse java 逆向工程_Mybatis 逆向工程的三种方法详解
Mybatis 逆向工程 逆向工程通常包括由数据库的表生成 Java 代码 和 通过 Java 代码生成数据库表.而Mybatis 逆向工程是指由数据库表生成 Java 代码. Mybaits 需要程 ...
- 三种方法详解斐波那契数列
本文同步.md文件,在展示上会有些许问题 原始版本在语雀平台.请各位移步查阅. 代码保存在码云平台供有需要者下载阅览. 本文采用暴力递归,带备忘录的递归,以及动态规划求解斐波那契数列.不到之处,欢迎指 ...
- Php 链式执行,PHP实现链式操作的三种方法详解
本文实例讲述了PHP实现链式操作的三种方法.分享给大家供大家参考,具体如下: 在php中有很多字符串函数,例如要先过滤字符串收尾的空格,再求出其长度,一般的写法是: strlen(trim($str) ...
- 链表逆置(三种方法详解)
@Achievek 6-1 单链表逆转 (20 point(s)) 本题要求实现一个函数,将给定的单链表逆转. ##函数接口定义: List Reverse( List L ); 其中List结构定义 ...
- 记录Nginx的升级实践以及实现的三种方法详解
方法一: 对于现在有的环境是通过源码包安装nginx的,由于库文件都存在,要升级nginx直接在虚拟机上编译安装好包 然后打包 ,更新到线上机器的/opt/nginx1.x上. 测试如下: scp n ...
最新文章
- 谁是创业板的支柱?兼驳《上海证券报》
- :link,:visited,:focus,:hover,:active详解
- mysql数据库truncate 夯住_MySQL如何优雅的删除大表实例详解
- SpringBoot学习笔记(4)----SpringBoot中freemarker、thymeleaf的使用
- filter过滤后重新添加_每天记一个单词(第3518)filter
- java 8 排序反转_Java 8 排序小结
- OpenCV人脸识别之一:数据收集和预处理
- 在写新邮件时,在地址栏中敲入前几个字母,对于已熟悉的收件人,outlook会弹出列表...
- 专卖店荣耀magicbookpro预装系统是Linux,换商家送的U盘里win10系统有影响吗?
- tftp的安装、设置以及put、get传输实验
- GitHub Package Registry 发布!你依旧是那个我们所爱的 GitHub!
- jQuery创建Dom元素
- 初次使用Chloe(本人小白)
- vue3 去除百度地图右上角地图类型展示
- deepin更新linux内核,修改deepin启动内核
- 华为 网络 链路捆绑
- Codeforces Round #545 (div 1.)
- oracle.net.ns.NetException:Socket read timed out update
- 个人站长那么难做,为什么还要学习SEO呢?
- 教你用C++ ChatRoom(CSocket)原理实现聊天室,附开源源码