zyf最喜欢的数字是1!所以他经常会使用一些手段,把一些非1的数字变成1,并为此得意不已。他会且仅会的两种手段是:
1.把某个数m除以某个质数p——当然p必须能整除这个数,即m=m/p
2.把某个数m减1,即m=m-1
有一天他突发奇想,想把[a,b]区间中所有的数一个一个地变成1,这是一个巨大的无聊的工程,所以他想知道他最少得花多少操作才能达到目的。
int search_deep(int num){ if(data[num] != 0){ return data[num]; } else { int temp = data[num - 1] + 1; int i = 0; /* 解法一 for(i = num / 2; i > 1; i--){ if(!prime[i] && num % i == 0 && search_deep(num / i) + 1 < temp){ // temp = search_deep(num / i) + 1; temp = data[num / i] + 1; } } */ // 解法二 for(i = 1; prime_array[i] <= num / 2; i++){ if(temp <= 2) break; if(num % prime_array[i] == 0 && data[num / prime_array[i]] + 1 < temp){ temp = data[num / prime_array[i]] + 1; } } return temp; } return 0; }
void generate(){ prime[1] = 1; prime[2] = 0; prime[3] = 0; int i = 0; int j = 0; int k = 1; for(i = 2; i < 100001; i++){ if(prime[i] == 0){ data[i] = 1; for(j = 2; i * j < 100001; j++){ prime[i * j] = 1; } prime_array[k++] = i; } } for(i = 2; i <= 100000; i++){ if(data[i - 1] + 1 < data[i]) data[i] = data[i - 1] + 1; for(j = 1; j < k && 1.0 * i * prime_array[j] < 100001; j++){ if(data[i] + 1 < data[i * prime_array[j]] || data[i * prime_array[j]] == 0){ data[i * prime_array[j]] = data[i] + 1; } } } }解法三的执行效率一下提高到了10ms左右!惊呼啊!主要是解法三的判断条件让程序去掉了很多没用的计算。