- 2023tyoi0292 的博客
divisor
- 2024-4-27 7:29:51 @
divisor
说实话,这道题一点都不毒瘤(感觉比签到题还简单)
思路:因为要最快减到一,所以最好是每次都少一半,也就是除以2,因此我就想到了把这个数变成2的次方,可以用这个玩意儿:while(n & (-n) != n) n = n & (n - 1)
,n & (n - 1) 是去掉二进制最右边一个1,n & (-n) 是去二进制最右边的1
AC code:
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
vector<int> ans;
int main() {
freopen("divisor.in", "r", stdin);
freopen("divisor.out", "w", stdout);
int t;
cin >> t;
while(t--) {
int n;
cin >> n;
ans.clear();
while((n & (-n)) != n) {
ans.push_back(n & (n - 1));
n = (n & (n - 1));
}
while(n > 1) {
ans.push_back(n / 2);
n /= 2;
}
cout << ans.size() << endl;
for(int i = 0; i < ans.size(); i++) cout << ans[i] << ' ';
cout << endl;
}
return 0;
}