等式的数字填充游戏-暴力破解的入门题
在暴力破解的相关题型中常常见到一种数字填充使等式成立的题目。这一类题目一般情况下又两种解法。
------------分割线君------------
其中一种是逐个变量进行可能性遍历。在这种方法中,我们的注意力主要集中在以下几点:
1、哪些未知量需要遍历?按照什么样的顺序进行遍历才能在循环层数最少的情况下算出结果?
2、对于某一个需要遍历的未知量,其遍历起点、终点各是什么?
3、后遍历的未知量是否受到前遍历未知量的限制?比如范围、形式、是否相等或是否有数字重复;
4、使用怎样的条件可以尽可能的减少循环次数,提高效率?
5、最终的判断成立的条件是什么?怎么记录?
一般情况下,这种题目都是多层循环嵌套及其相关分析。做这种题目时,一定要先对遍历循环层数有一个大致的描述,确定复杂程度。这是必须清醒的认识到的。
------------分割线君------------
第二种解法往往见于填入数字已经确定且要求不重复的特殊情形下。在这种情况下,上述遍历虽然有可行性,但往往复杂度太高。而出题人的中心基本落在 暴力+排列组合 上。此时,就可以通过algorithm头文件中的next_permutation()函数进行开快速遍历。同时,将解题重心放在 如何对某一序列的各个元素进行组合 上。此时需要考虑的是组合形式与验证方案。值得一提的是,对于0到9这是个数字,遍历其全排列的过程并不缓慢。对于计算机来说是相当迅速的。
------------分割线君------------
下面是蓝桥杯的一个真题。
问题描述 100 可以表示为带分数的形式:100 = 3 + 69258 / 714。 还可以表示为:100 = 82 + 3546 / 197。 注意特征:带分数中,数字1~9分别出现且只出现一次(不包含0)。 类似这样的带分数,100 有 11 种表示法。 输入格式 从标准输入读入一个正整数N (N<1000*1000) 输出格式 程序输出该数字用数码1~9不重复不遗漏地组成带分数表示的全部种数。 注意:不要求输出每个表示,只统计有多少表示法!
我注:表示形式N=a+b/c
利用第二种方案进行解答时,我们仅仅需要考虑如何组合数字并验证即可。而如果使用第一种方案,虽然可能在N较小的情况下比较迅速,但是随着N的增大,遍历的复杂度会急剧增大。可以很容易的看出,分数中分子和分母的大小可以远远超过N的大小,这使得遍历更加复杂。
使用第二种方案:我发现分数一定时可以约分成整数的。所以分子一定比分母大。(并不严谨的)换句话说,就是分子的位数不能小于分母。这时,我可以先对分解式中的a确定一个位数,并从排列中分配其对应个数的数字。然后将剩余的数字分配。最后验证即可。内层循环的结束条件是:当分母的分不到数字时,结束内层循环。
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 int counts; 7 int num[10]; 8 int n; 9 10 int main() 11 { 12 for(int i=1;i<10;i++) 13 { 14 num[i-1]=i; 15 }//填充9个数字 16 cin>>n; 17 //int s=500; 18 do 19 { 20 //s--; 21 //for(int i=0;i<9;i++)printf("%d ",num[i]); 22 //printf("\n"); 23 // 24 int cur=0; 25 int a=0,b=0,c=0; 26 for(int i=1;i<=9;i++) 27 { 28 for(;cur<i;cur++)a=a*10+num[cur];//获取a 29 if(a>=n)break; 30 // 31 int wei=9-i;//剩余的数字个数 32 int weic=wei/2;//c的最大位数 33 for(;weic;weic--) 34 { 35 int weib=wei-weic;//b的位数 36 for(;cur<i+weic;cur++)c=c*10+num[cur]; 37 for(;cur<9;cur++)b=b*10+num[cur]; 38 //printf("%d-%d-%d\n",a,b,c); 39 if((n-a)*c==b)counts++; 40 b=0,c=0,cur=i; 41 } 42 } 43 // 44 }while(next_permutation(num,num+9)); 45 printf("%d\n",counts); 46 return 0; 47 }
提交结果:
带分数 | 03-03 16:42 | 829B | C++ | 正确 | 100 | 31ms | 2.503MB |
OK