#include <iostream>
#include <algorithm>
#include <vector>
#include <bitset>
#include <string>
using namespace std;
string trans_string(long long input){
// if(input == 0) {
// return "0";
// }
string result;
while (input > 0){
if (input % 2 ==0){
input /= 2;
result = "0" + result;
}
else {
input /= 2;
result = "1" + result;
}
}
return result;
}
int fx(long long x){
string a = trans_string(x);
int n = 0;
int length = a.length();
for (int i = 0; i < length;i++){
if(a[i] == '1'){
n++;
}
}
return n;
}
int gx(long long y){
string b = trans_string(y);
int m = 1;
int length = b.length();
for(int j=0;j < length;j++){
if(b[j] == '0'){
m++;
}
}
return m;
}
int main(){
long long x;
cin >> x;
while(x != gx(fx(x))){
x = gx(fx(x));
}
cout << x ;
return 0;
}
首先对题目分析知道 关键在于1构建fx gx两个全局函数 2将输入值转化成为“无前导零”的二进制字符串 3对字符串使用fx gx等操作直至 满足x 恒等于x0
但是在执行时先后遇到了如下问题
1在尝试将输入转化成为二进制字符串时候 第一次尝试了bitset库中的bitset实例与to_string方法
string toBinaryString(long long number) {
bitset<64> bits(number); // 32位,可根据需要调整
return bits.to_string();
}
但是这样的题是 输入假如是1 那么转化后的字符串就是 00000000000000000000000000000000001,前面63位都是前导零,这样在遍历时候就会把前面的零全部遍历一遍啊
那么要去掉前导零 有两个方法 一种还是bitset库
string toBinaryWithoutLeadingZeros(int number) {
if (number == 0) return "0";
bitset<32> bits(number);
string binary = bits.to_string();
// 找到第一个'1'的位置,移除前导零
size_t firstOne = binary.find('1');
if (firstOne != string::npos) {
return binary.substr(firstOne);
}
return "0";
}
但是我使用了另一种不使用bitset的方法 这样的方法是通过二进制转化原理 对于输入取2的模 如果能除以二 那么就在创建的空白字符串的头部加一个“0”
result = "0" + result
能除以2 就在头部添加一个“1”
result = "0" + result
注意 如果输入的是0 那么应该直接输出0
第一次时候我把 0和 1弄反了 所以输出了目标的反码 10001变成01110 导致输出的答案变成了二而不是一
————————————————————————————————————————————————————————————————————————————————这是分隔符————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
那么构造了转化的函数之后 现在应该构造fx和gx了
第一次在fx内对输入的x使用trans_string函数时侯 我使用了.trans_string()方法
然而这样是错的 为什么呢
- 基本数据类型(Primitive Types) int, long, long long, float, double, char 等
没有成员方法,不能使用 . 操作符调用方法
只能通过全局函数或运算符操作
cpp
long long x = 42;
// x.to_string(); // 错误:long long 没有成员方法
2. 类类型(Class Types)
std::string, std::vector, std::bitset 等
有成员方法,可以使用 . 操作符调用方法
cpp
string a = "hello";
a.length(); // 正确:string 是类,有成员方法
基本类型像原始工具(锤子、螺丝刀),你直接使用它们,但它们本身没有"功能按钮"
类类型像智能设备(手机、电脑),它们有各种内置的功能和方法
// 基本类型 - 像原始工具
int number = 10; // 就像一个数字10,没有额外功能
// number.doSomething(); // 错误:数字本身没有功能
// 类类型 - 像智能设备
string text = "hello"; // 像一个字符串对象
text.length(); // 正确:对象有内置功能
另外,在fx gx内部 判断if(b[j] == '0')而应该是0 进行比较的是字符而不是int值