Make a Power of Two(思维,字符串)

题目

Make a Power of Two


问题描述

给定一个小于等于 1 0 9 10^9 109的正整数 n n n,此时有两种操作,

操作一:在数字 n n n的右端添加一位数字;

操作二:在数字 n n n中擦除一位数字,要保证擦除这一位数字后不会出现前导0,比如在 ′ 30 1 ′ '301' 301中不能擦除数字 3 3 3,否则会出现 ′ 0 3 ′ '03' 03,产生前导0.

问数字 n n n可以变为 2 2 2的幂所经历最少的操作数。


分析

算思维题吧,根据数据范围,所以由 n n n操作所能变为的 2 2 2的幂其实是很有限的,

反过来思考就是先求出 n n n变为某个2的幂所需要的操作数,并且从所有情况的操作数中选出一个最小的作为最终结果输出。

那么下一个问题就是如何求 n n n变为某个2的幂所需要的操作数。
150 150 150为例,求变为 1024 1024 1024所需要的操作数

设置一个量为 t m p tmp tmp t m p tmp tmp初始值为 0 0 0
再设置两个量 a 、 b a、b ab,作为指针记录在 150 150 150 1024 1024 1024上所处的位置,

先第一轮比较,1与1相同,则 t m p + + tmp++ tmp++,同时 a + + 、 b + + a++、b++ a++b++看下一位;

第二轮比较,5与0不同,这个时候直接让 a + + a++ a++,而 t m p tmp tmp b b b则不进行操作;

第三轮比较,0与0相同,同样 t m p + + tmp++ tmp++,同时 a + + 、 b + + a++、b++ a++b++看下一位;

第四轮发现 a a a已经超出范围,那么结束比较。

在结果中,由 150 150 150的长度3减去 t m p tmp tmp的值就是需要进行删除操作的操作数,由 1024 1024 1024的长度减去 t m p tmp tmp的值就是需要于右端添加的操作数,两数之和就是总操作数。

最大的收获应该是了解了函数 t o _ s t r i n g to\_string to_string,可以将数字直接转化为string
在这里插入图片描述

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const ll P2LIM = (ll)2e18;

int solve(string s, string t)
{
	int tp = 0;
	int sp = 0;
	int taken = 0;

	while (sp < s.length() && tp < t.length())
	{
		if(s[sp] == t[tp])
		{
			taken++;
			tp++;
		}
		sp++;
	}

	return (int)s.length() - taken + (int)t.length() - taken;//前为删除操作数,后为添加操作数 
}

vector<string> ts;

int main()
{
	for (ll p2 = 1; p2 <= P2LIM; p2 *= 2)
		ts.push_back(to_string(p2));

	int t;
	cin >> t;

	while (t--)
	{
		string n;
		cin >> n;

		int ans = n.length() + 1;
		for (auto p2 : ts)
			ans = min(ans, solve(n, p2));
		cout << ans << endl;
	}

	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值