问题
用1到9组成一个9位数,使得这个数的第一位能被1整除,前两位组成的两位数能被2整除,前三位组成的三位数能被3整除,以此类推,一直到整个九位数能被9整除。
分析
先看看计算机最擅长的事——遍历。假如让i从1e8到1e9遍历9亿次,每一次进行一次上述判断…好吧,我等了十几分钟,没有结果。这样做效率太低了。
再看看题干,由1~9组成的九位数,可以用1 ~9的全排列计算。这样只需算9!=362880个数。但是计算次数还是很多,需要继续优化。
需要对条件进行进一步分析。
进一步,需要知道在题设条件下1~9整除的数字的特点:
被2整除:偶数。
被3整除:前三位数之和是3的倍数。
被4整除:末尾两位数能被4整除。
被5整除:5和0,在题设条件下,只有5。
被6整除:同时被2和3整除。
被7整除:判断方法有好多种,处理不方便。
被8整除:最后三位数是8的倍数。
被9整除:各个位上数字之和为9的倍数,在题目条件下,这一条恒成立。
发现第五位是最好处理的。之后偶数位上至少满足的条件得是个偶数。这样可以对奇数位和偶数位分别处理,只需要计算4!*4!=576个数。同时不需要进行前五位数被5整除这一个判断。按照这种思路写出了初代代码如下:
初代:
由于用字符更好操作,所以使用字符进行全排。
在一些地方,直接用公式计算了,没有做优化。
代码如下:
#include<stdio.h>
#include<string.h>
int num,num_odd[24],num_even[24],n;
void swap(char *str1,char *str2)
{
char temp;
temp=*str1;
*str1=*str2;
*str2=temp;
}
//全排列函数
void Allarrange(char *str,int i,int flag)
{
if(i=&