利用二进制解决问题 && 十进制转为二进制

拼多多笔试题–多多培养细胞

#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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值