打表法和模拟法
例题1:
题目描述:
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
看这个算式:
☆☆☆ + ☆☆☆ = ☆☆☆
如果每个五角星代表 1 ~ 9 的不同的数字。这个算式有多少种可能的正确填写方法?
173 + 286 = 459
295 + 173 = 468
173 + 295 = 468
183 + 492 = 675
以上都是正确的填写法!
注意:111+222=333 是错误的填写法!因为每个数字必须是不同的!也就是说:1 ~ 9 中的所有数字,每个必须出现且仅出现一次!
注意:不包括数字 “0”。
注意:满足加法交换率的式子算两种不同的答案。 所以答案肯定是个偶数!
运行限制:
1. 最大运行时间:1s
2. 最大运行内存: 128M
题目分析:
这个题的正解是搜索算法, 只需要答案, 使用模拟方法:
-
这里有三个数字 我们称 A + B = C 且各个位上的数字不同。
-
我们这里借助桶排序的思想来判断 1-9 这些数字有没有占用。我们定义一个判断函数,用于判断 A B C 三个数字是否符合要求。
-
暴力枚举:
- A 从 123 到 987 开始枚举
因为 123 是最小的符合要求的数字,可以减少枚举的次数,987 是最大的符合要求的数字。
- B 从 123 到 987-A 枚举
为什么不直接枚举与 A 不一样的数字呢,那么又得考虑每一位的问题,这样的模拟已经不是暴力法了,我们要做的就是在不改变完成难度的情况下,减少复杂度。所以要分清注次。
- C = A + B 这时候只要检查 A B C 是否符合要求即可。
补充知识点:桶排序
桶排序的思想是,若待排序的记录的关键字在一个明显有限范围内时,可设计有限个有序桶,每个桶只能装与之对应的值,顺序输出各桶的值,将得到有序的序列。简单来说,在我们可以确定需要排列的数组的范围时,可以生成该数值范围内有限个桶去对应数组中的数,然后我们将扫描的数值放入匹配的桶里的行为,可以看作是分类,在分类完成后,我们需要依次按照桶的顺序输出桶内存放的数值,这样就完成了桶排序。
代码实现:
package 打表法和模拟法;
public class T1 {
//1. 定义一个判断函数,用于判断 A B C 三个数字是否符合要求。
//要求:借助桶排序的思想来判断 1-9 这些数字有没有占用
static int check(int a,int b,int c) {
int flag[] = new int[11];
//相当于此处有10个桶
for(int i=0;i<10;i++) {
flag[i] = 0;
}
flag[0] = 1;
while(a!=0) {
//对a值判断
if(flag[a%10]==1) {
return 0;
}
else {
flag[a%10]=1;
}
//对b值判断
if(flag[b%10]==1) {
return 0;
}
else {
flag[b%10]=1;
}
//对c值判断
if(flag[c%10]==1) {
return 0;
}
else {
flag[c%10]=1;
}
//更新a,b,c
a = a/10;
b = b/10;
c = c/10;
}
return 1;//符合要求
//比如:173 + 286 = 459
//a=173 b=286 c=459
//173%10=3 286%10=6 459%10=9
//a =173/10=17 b=286/10=28 c=45
//17%10=7 28%10=8 45%10=5
//a = 17/10=1 b=2 c=4
//a%10=1 退出了while循环 在此过程始终没有return 0
//则return 1 就代表a b c符合要求
}
public static void main(String[] args) {
int count = 0;//统计可以成立的式子的个数
for(int a=123;a<=987;a++) {
for(int b=123;b<=987-a;b++) {
int c = a+b;
if(check(a, b, c)==1) {
count++;
System.out.println(a+"+"+b+"="+c);
}
}
}
System.out.println(count);
}
//336
}
Java 提交答案代码:
public class Main {
public static void main(String[] args) {
System.out.println(336);
}
}
例题2:
题目描述:
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
学习了约数后,小明对于约数很好奇,他发现,给定一个正整数 t,总是可以找到含有 t 个约数的整数。小明对于含有 t 个约数的最小数非常感兴趣,并把它定义为 St。
例如 S1=1,S2=2,S3=4,S4=6,⋅⋅⋅
现在小明想知道,当 t=100 时,S100 是多少?
运行限制:
1. 最大运行时间:1s
2. 最大运行内存:128M
补充:
约数:又称因数。整数a除以整数b(b≠0) 除得的商正好是整数而没有余数,我们就说a能被b整除,或b能整除a。a称为b的倍数,b称为a的约数。
一个数的约数必然包括1及其本身。
如果一个数c既是数a的因数,又是数b的因数,那么c叫做a与b的公因数。
两个数的公因数中最大的一个,叫做这两个数的最大公因数。
分析:
是一道数论题目,由于是道填空题,所以我们采用模拟法打表做。
我们定义个找约束个数的函数,然后枚举即可。
代码实现:
package 打表法和模拟法;
public class T2 {
//找某个数字的约数的个数
static int cnt(int a){
int ans = 0;
for (int j = 1; j <= a; j++)
if (a % j == 0)
ans++;
return ans;
}
public static void main(String[] args) {
for(int i=1;true;i++) {//从1开始,按从小到大顺序查找,可以保证含有 t 个约数的最小数
System.out.println(i+"的约数的个数是"+cnt(i));
if(cnt(i)==100) {
break;
}
}
}
//45360的约数的个数是100
}
例题3:
题目描述:
本题为填空题,只需要算出结果后, 在代码中使用输出语句将所填结果输出即可。
如果一个分数的分子和分母的最大公约数是 1,这个分数称为既约分数。
例如:3/4 1/8
请问,有多少个既约分数,分子和分母都是 1 到 2020 之间的整数(包括 1 和 2020)?
运行限制
1. 最大运行时间:1s
2.最大运行内存:128M
题目解析:
现在一眼就知道只是到纯暴力的题目,即暴力枚举然后依据题目要求模拟即可。
这题目我们首先要两个数是否互质,即最小公约数为 1,我们就定义一个 GCD() 求最小公约数的算法 ,采用的是递归的方法。
一般我们按照如下写法:
int GCD(int a,int b)
{
return a%b?GCD(b,a%b):b;
}
也可以同义的替换成一下写法:
int GCD(int a,int b)
{
if(a%b==0) return b;
//如果a%b==0 代表可以被整除,那么b就是最大公约数
else return GCD(b,a%b)
// 如果不能被整除,那么就先取余数,代码会保证左侧是大的,右侧是小的数字,所以使用时不必进行大小检查,即使a<b也会再一次递归后变成b,a在进行计算。
//这样就能按照辗转相除法求解。
}
当让也可以:
int gcd(int a,int b)
{
int temp;
while(b)
{
/*利用辗除法,直到b为0为止*/
temp = b;
b = a % b;
a = temp;
}
return a;
}
然后这个题目我们就可以进行枚举了。
代码实现:
package 打表法和模拟法;
public class T3 {
// 求最小公约数 利用辗除法,直到b为0为止
static int gcd(int a,int b) {
int temp;
while(b>0) {
temp = b;
b = a%b;
a = temp;
}
return a;
}
public static void main(String[] args) {
int count = 0;
for(int a=1;a<=2020;a++) {
for(int b=1;b<=2020;b++) {
if(gcd(a, b)==1) {
count++;
}
}
}
System.out.println(count);
}
//2481215
}
总结:
对于这种简单的模拟题,不需要借助算法,只要暴力的题目,我们都可以打表模拟
多做简单的思维题,进行训练才能为后期的算法学习打下良好的基础
那些思维很好的同学,即使某一道题的算法我不会,但是我会有新的想法能接触这道题,我们现在所接触的所有算法,不都是某一个大牛,在不经意间发现,经过各种优化到我们手里的
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现