拼多多笔试题–多多培养细胞
#include<iostream>
#include<string>
#include<vector>
#include<cmath>
#include<algorithm>
using namespace std;
//int feeddaynum(int feedday, int shengyu,vector<int>& day) {
// //喂养的天数 剩余的细胞数
// if (shengyu == 1) {
// feedday++;
// day.push_back(feedday+1);
// return feedday;
// }
// if (shengyu == 2) {
// feedday++;
// day.push_back(feedday);
// feedday += 2;
// return feedday;
// }
// /*else {
// feedday++;
// day.push_back(feedday);
// feedday--;
// }*/
//}
//
//int main() {
//
// int T, N;
// cin >> T;
// int feedday = 0;
// vector<int> day; //培养了多少天
//
// for (int i = 0; i < T;i++) {
// cin >> N; //表示细胞总数
// if (N == 1 && T == 1) {
// cout << 1 << endl;
// cout << 1 << endl;
// return 0;
// }
// if (N == 2 && T == 1) {
// cout << 2 << endl;
// cout << 1 << endl;
// system("pause");
// return 0;
// }
//
// double res = log(N)/log(2);
// int y = log(N) / log(2);
//
// if (res == y) { //只在第一天放入细胞的情况
// cout << (y+1) << endl;
// cout << 1 << endl;
// system("pause");
// return 0;
// }
// else { //分多次放入细胞
// feedday = y; //现在培养了多少天
// day.push_back(1);
// int shengyu = N - pow(2,y); //剩余细胞的数量
// feedday = feeddaynum(feedday,shengyu,day);
//
// cout << feedday << endl;
// for (int i = 0; i < day.size(); i++) {
// cout << day[i] << " ";
// }
// }
//
// }
//
// system("pause");
// return 0;
//}
/*
多多培养细胞
*/
//int main() {
// int T;
// cin >> T;
// int N; //细胞的数量
//
// int feedday = 0;//喂养的天数
// vector<int> fd; //存放喂养的天数
// vector<vector<int>> n;//存放加入细胞的序列
//
// for (int i = 0; i < T;i++) {
// cin >> N;
// vector<int> num; //存储第几天放入的细胞
//
// feedday = (log(N) / log(2)) + 1; //这个决定了喂养的总天数;因为无论怎样,第一天是有一个细胞在增长的;可以根据第一个细胞的数量判断出总的天数
// int shengyu = N - pow(2,feedday-1); //除去第一天的细胞还有多少细胞
// num.push_back(1);
// while (shengyu != 0) { //逐渐判断细胞是何时加进去的,直到没有细胞判断
// int tmp = log(shengyu) / log(2); //剩下的细胞中最早加入的生成的细胞个数
// num.push_back(feedday-tmp);
// shengyu -= pow(2,tmp);
// }
//
// fd.push_back(feedday);
// n.push_back(num);
//
// }
//
// for (int i = 0 ; i < n.size(); i++) {
// cout << fd[i] << endl;
// for (int j = 0; j < n[i].size(); j++) {
// cout << n[i][j] << " ";
// }
// cout << endl;
// }
//
//
// system("pause");
// return 0;
//}
/*
第二种思路:
仔细观察可以发现:在哪一天加入的细胞取决于细胞总数的二进制上表示上哪一位为1;通过思路一也可以看出来,
其实每次在求的都是剩余数量中那个最高位的二进制位的位置。
*/
void convert_10_to_2(int N,vector<int>& binarynum) {
//根据辗转相除法的思想
while (N!=0) {
binarynum.push_back(N % 2);
N = N / 2;
}
//将辗转相除法的结果逆序存放到数组中
reverse(binarynum.begin(),binarynum.end());
}
int main() {
int T;
cin >> T;
int N; //细胞的数量
int feedday = 0;//喂养的天数
vector<int> fd; //存放喂养的天数
vector<vector<int>> n;//存放加入细胞的序列
for (int i = 0; i < T; i++) {
cin >> N;
vector<int> whichdayadd;
vector<int> binarynum; //存放数的二进制
//十进制转二进制
convert_10_to_2(N,binarynum);
//测试是否正确转为二进制
/*for (int i = 0; i < binarynum.size(); i++) {
cout << binarynum[i];
}*/
//统计天数 -- 转成二进制的长度 即 天数(可以理解为第一个细胞培养的天数即是总天数)
fd.push_back(binarynum.size());
//统计哪一天加入 -- 哪一个二进制位上是 1 即为哪一天加入(可以逆向思维,从最后一天生成的个数推导哪一天加入的)
for (int i = 0; i < binarynum.size(); i++) {
if (binarynum[i] == 1) {
whichdayadd.push_back(i+1);
}
}
n.push_back(whichdayadd); //将这一种情况加入结果集
}
for (int i = 0; i < n.size(); i++) {
cout << fd[i] << endl;
for (int j = 0; j < n[i].size(); j++) {
cout << n[i][j] << " ";
}
cout << endl;
}
system("pause");
return 0;
}