1 问题描述
有一种数字,叫做beautiful numbers,当且仅当它的二进制表示是先由 k+1 个1,再由 k 个0组成的。比如:
而在十进制表示时,有一种更方便的检验方法。如果 n 是一个beautiful number,那么
任务:输入一个正整数,输出它的除数中,最大的beautiful number。注意,一定会有输出的,因为再不济,1就是一个beautiful number。
2 我的编程思路
给一个数 n ,由于它的除数肯定不会超过自身的一半,所以:
1. 先得到 n 的 1/2 位置的数 p;
2. for循环从 p 递减到 1,每次循环,先判断是否为 n 的除数,然后判断是否是beautiful number;
3. 一旦上述两个判断皆为 true,那么可以直接输出,终止程序了
上述思路明显有个漏洞,导致我没有被ac。即漏掉了 n 自身就是一个 n 的除数。考虑欠周啊!
3 我的代码
给出我的改后的ac代码:
#include <cmath>
#include <cstdio>
#include <iostream>
using namespace std;
bool isBeautiful(int num) {
int cpn = num, bits = 0;
while(cpn) {bits++; cpn /= 2; }
if(bits % 2 == 0) return false;
else {
int k = (bits+1) / 2;
if( (pow(2.0, (double)k ) - 1) * pow(2.0, (double)(k-1)) == num )
return true;
else
return false;
}
}
int main() {
int n;
while (cin >> n) {
if(isBeautiful(n)) {
cout << n << endl;
continue;
}
for (int i = (n+1) / 2; i > 0; i--) {
if( n % i == 0 && isBeautiful(i) ) {
cout << i << endl;
break;
}
}
}
return 0;
}
4 高手代码
看一位紫君的代码:
#include<cstdio>
int main(){
int n;
scanf("%d", &n);
int t = ((1<<10)-1)<<9;
while (n % t != 0){
t -= t&-t;
t >>= 2;
}
printf("%d\n", t);
}
这些位操作厉害了……不过据搞比赛的师弟说,位操作比较非主流……哈哈,那就先不分析了。