学会了拆分的应用
前几天做了一道题,要求如下:
将 1, 2, ……,9共 9 个数分成 3 组,分别组成 3 个三位数,且使这 3 个三位数构成 1 : 2 : 3 的比例,试求出所有满足条件的 3个三位数。无输入,输出若干行,每行 3 个数字,按照每行第 1个数字升序排列。(注意,这九个数不能重复使用)
刚开始没有思路,也不会写拆分函数,单个拆分会很麻烦,无从下手。后来看了他人的题解,加上男朋友的在旁解释,终于看懂并用过运用拆分把题做出来了。
这道题借助了一个数组n[10]进行计数(这里我学到了一个小知识,数组要在main函数外定义,我之前一直都在main函数里直接定义),如果1-9中对应的数i出现过,就将n[i]置为1,最后如果n[1]-n[9]都为1,可以证明九个数字都用到了且没有重复使用的情况(如果重复,会有某个n[i]不为1的,不满足条件)。
由于每个数都是一个三位数,所以使用了3个for循环以枚举的方式组成第一个三位数,并通过1:2:3的比例,找出对应的另两个三位数。找到数后,运用自己定义的一个拆分函数,通过while循环将三位数x的每一位进行拆分(求出个位:x%10 后将三位数整除10变成两位数 x/10 将对应的n[个位]置为1,再循环求两位数的个位也就是原来的十位),三个三位数都拆分完后,数组n[10]的对应位都置为1了,判断满足1-9都为1的,将三个三位数输出,继续向下找其他的……
#include<iostream> #include<cstdlib> using namespace std; int n[9]; //计数 //拆分函数 int cf(int x) { int gw=0; //个位 while(x!=0) { gw=x%10;//取模求出个位 x=(x-gw)/10;//整除10 方便下次循环求三位数的十位 n[gw]++; //对应位置为1 } } int main() { int a1,a2,a3; int i,j,k; for(i=1;i<=9;i++) { for(j=1;j<=9;j++) { for(k=1;k<=9;k++) { a1=i*100+j*10+k;//由i,j,k组成的第一个数 a2=a1*2;//由比例计算的第二个数 a3=a1*3;//由比例计算的第三个数 cf(a1);//调用拆分函数 cf(a2); cf(a3); if(n[1]==1&&n[2]==1&&n[3]==1&&n[4]==1&&n[5]==1&&n[6]==1&&n[7]==1&&n[8]==1&&n[9]==1)//判断是否1-9都用到 { cout<<a1<<" "<<a2<<" "<<a3<<endl;//输出 } for(int q=1;q<=9;q++)//将n[10]数组清零,方便下次计数 { n[q]=0; } } } } return 0; }
做完这个题后,当晚又做了一个拆分类型的题巩固了一下,以为自己掌握了,但是今天自己找题做的时候,又发现了一道题要用到拆分知识,发现不能熟练和灵活运用。看了看前面的代码才想起来,又根据这个题的不一样要求进行了改变,才做出题来,所以今天想起来写一写,归纳一下拆分的应用。